Back to site

Java Гласарый

Зразумеў гэта непрыемны сюрпрыз на мове Java або стандартныя бібліятэкі. Хтосьці можа называць іх памылак, некаторыя асаблівасці. Часам яны з'яўляюцца вынікам некампетэнтнасці або нядбайнасці з боку мовы дызайнераў, а часам яны проста мудрагелістыя рэчы, якія не можа быць аказана дапамога. Вось схема некаторых небяспечных водах.

Я казаў на гэтую тэму ў 1997-11 у Каларада канферэнцыі на вышэйшым узроўні, а затым у 1999-11.

Gotcha Цяжкасці
Непаслядоўнасць пашырэнняў 1
Мы не ў Канзасе Больш
Асноўныя адрозненні ад C
1
Па змаўчанні праваліцца 1
String.Replace 1
Мікраскапічныя шрыфты 1
Сепаратар супраць Тэрмінатара 1
Двухмесны працы і Праблемы 1
Неадпаведнасці 2
ToString блюз 2
Бяссільны злепкі 2
Характарызуецца характар ??або колькасць? 2
Васьмярковым 2
Выпадак знікнення Канструктары 2
Адсутнічае Hex 2
Math.sin 2
Дзе Beep? 2
Дзе каранёвай каталог? 2
для кожнага 2
Unstoppable для 2
Справа Сюрпрызы Верхняй 2
Бездапаможны Shift 2
String.substring 2
Непараўнальны NaN 2
String Параўнанне 2
StringBuffer.equals 2
ValueOf і нуль 2
Заключны супраць Const 2
Перапаўненне 2
BigDecimal Параўнанне 3
Змена супраць Ценяў 3
"Зламаная" setLocation, SetSize, setBackground, setForeground 3
Бяззнакавыя байтаў 3
Модуль 3
Array ініцыялізацыі 3
Array Параўнанне 3
Матрыца ініцыялізацыі 3
ArrayStoreException масіваў сабак і далмацін 3
Статычныя Initialisers 3
Асобнік Initialisers 3
Канструктар ініцыялізацыі 3
Злепкі далмацін сабакі 3
Няяўныя злепкі 3
Канкатэнацыі 3
addChangeListener 3
М у O utput L ooks L Айк T яго 3
Аператары прысвойвання каскадныя 3
Псеўда выпадковых лікаў 3
Финализаторы Не деструкторы 3
Нарэшце 3
Ніцевыя 3
java.math.BigDecimal 3
java.util.Date 4
java.util.GregorianCalendar 4
java.awt.Graphics.drawRect 4
java.awt.Graphics.drawString 4
GridBagLayout 4
Null Макет 4
Састарэлыя Blues 4
java.io.BufferedReader і BufferedInputStream 4
Аплеты не можа выкарыстоўваць лакальны жорсткі дыск 4
Адноўленая сериализованных аб'ектаў 4
"Broken" перафарбоўку 4
Схаваная кампаненты не застанецца незаўважанай 4
Dialog.setBackground не працуе 4
Тэмы 4
Socket To Me 4
Націск клавішы назвах 4
Імпарт Blues JSP 4
TableCellRenderer 4
Якія ўводзяць у зман паведамленні аб памылках 5
Крэдыты -
Кнігі -

Непаслядоўнасць пашырэнняў

Часам пашырэнне павінна быць відавочна, напрыклад, *. Java пры кампіляцыі, або *. класа пры выкананні. Можна падумаць, пашырэнне будзе факультатыўным. Гэта не так. Часам вы павінны выбраць яго, і часам вы не павінны. І часам вы можаце сысці з рабіць гэта ў любым выпадку, на некаторых платформах. Вось правілы, якія будуць працаваць заўсёды.
Непаслядоўнасць пашырэнняў
Дзе Пашырэнне Абавязковае? Прыклад
складанне mandatory
CD \MyDir
javac.exe -classpath . HelloWorld.java
executing must exclude
CD \MyDir
java.exe -classpath . HelloWorld
Applet mandatory
<applet

code="HelloWorld.class"
width="230"
height="240">
<img src="image/NoJava4U.jpg">

</applet>

We Aren’t In Kansas Anymore

C/C++ programmers will attempt to write code like

if ( width )

   {
   widen( width );
   }
if ( myDog )

   {
   myDog.bark();
   }
Вы павінны гэтыя загаворы з звычайнае ліст у Java:
if ( width != 0 )
   {
   widen( width );

   }
if ( myDog != null )
   {
   myDog.bark();

   }

However, for

if ( tooWide )
   {
   widen( width );

   }

Beware, you

if ( tooWide = true )
   {
   widen( width );

   }
Звярніце ўвагу: што = вышэй, аператар прысвойвання, а не == аператар параўнання. Калі заўсёды праўдзіва.

Па змаўчанні праваліцца

З праграмісты знаёмыя з гэтым, але тых, хто прыбывае з моў распрацавана прафесарам Віртам будуць задыхацца ў здзіўленні

switch ( k )

   {
   case 1:
      System.out.println( "hello" );

   case 2:
      System.out.println( "hi" );

   }
Калі да 1, праграма выведзе як "прывітанне" і "прывітанне". Справа становішча падзення, хоць па змаўчанні. Вы не будзеце атрымліваць памылкі сінтаксісу ці нават папярэджанне, калі вы пакінеце з перапынак пасля кожнага выпадку.

Паколькі сінтаксіс для вызначэння выпадкаў і этыкеткі так падобны, гэта лёгка зрабіць памылку, як гэта: праграміст з левага прасторы і, замест апрацоўкі п == 3, ён вызначыў перайсці да пункта называецца case3 ў сваёй заяве пераключальніка.

У Java версіі 1.4 або больш позняй версіі Вы можаце выкарыстоўваць javac.exe-Xswitchcheck атрымаць кампілятар папярэдзіць вас, калі вы робіце гэта. Аднак, няма сінтаксісу сказаць Java, калі вы мелі на ўвазе, каб зрабіць гэта наўмысна, напрыклад, выпадку перапынку або Правальваемся ключавое слова.

String.Replace

 //String.Replace выпускае новую радок. Ён не змяняе арыгінальны.
// Since String is immutable, no method can modify the original.

String aa = "peal";
String bb = aa.replace( 'a', 'e' );

System.out.println ( aa + " " + bb );

// Prints "peal peel" not "peel peel"
// Newbies often expect String aa to be changed too.
String. Замяніць не змяняе ўваходны радка. Ён не мог, нават калі ён хацеў, так як String S з'яўляюцца нязменнымі. Акрамя таго, Javadocs для замены растлумачыць, што замяніць стварае новую радок.
Дакументацыя на's String. Oracle замяніць: у наяўнасці:
Гэта Зразумеў гэта не віна Sun. Тое ж самае ставіцца да String. ToUpperCase і String. ToLowerCase.

Мікраскапічныя шрыфты

Часам шрыфты выйдзе занадта малы, каб бачыць. Хутчэй за ўсё гэта азначае, што вы цалкам змянілі Апошнія два параметра пры стварэнні шрыфта, памылкі кампілятар не можа вызначыць, так як шрыфт не выкарыстоўваць пералік с, толькі што пералічаныя канстанты Int.
 //На жаль, НЕ РАБІЦЕ ГЭТАГА!
кампанент). SetFont (новы шрыфт ("Дыялог", 12, тоўстым шрыфтам.);


// do this instead:
component.setFont( new Font( "Dialog", Font.BOLD, 12 ));

Шрыфт. CreateFont вырабляе шрыфта 1 бал высокі, занадта малы, каб бачыць. Вы павінны выкарыстоўваць шрыфт. DeriveFont перш чым вы зможаце выкарыстоўваць яго.

Сепаратар супраць Тэрмінатара

Java даволі loosey Гусі аб выкарыстанні сепаратараў і тэрмінатараў.

Двухмесны працы і Праблемы

Кампілятар для моў, такіх як Эйфелева праходзіць Houdiniesque скажэнні, каб вы ставіцеся да прымітывы як аб'екты адначасова даючы прымітываў выказаць лячэння, калі вам не трэба прадметнасці. У такіх мовах, вы можаце напісаць код, аналагічны наступнага:
/ * Гэта не будзе працаваць у Java! */
int ii = -42;
int jj = ii.abs();
String s = ii.toString();
Але ў Java, вы не можаце выкарыстаць метады экзэмпляра на прымітывы. Тым не менш, вам усё роўна прыйдзецца набор стандартных метадаў для вырашэння байт S, кароткі S, сімвал S, Int S, паплавок S і двойчы s. Так нд стварылі мноства класаў называецца Byte, Short, характар ??(не Char), Integer (не Int), Float і Double. Яны пісалі усё, каб важдацца з прымітывы як статычныя метады! Што яшчэ яны могуць зрабіць?

Вы павінны ставіцца да прымітывы як аб'екты для іншай мэты - так, што вы можаце змясціць іх у кантэйнеры, такія як ArrayList S або вектара s. У Java, вы павінны ўручную абгарнуць прымітыўных ў аб'ект. Нд падае набор нязьменных класаў абгорткі аб'ект пад назвай: Byte, Short, характар ??(не Char), Integer (не Int), Float і Double, той жа класах, што ваш дом статычныя метады для махінацый з прымітываў! Гэта можа быць ясней, калі б яны назвалі гэтыя класы імёны, як ImmutableByte або ByteWrapper, але яны гэтага не зрабілі. Вы не можаце змяніць значэнне прымітыўных ўнутры любога з гэтых аб'ектаў абалонкі. Усё, што вы можаце зрабіць, гэта стварыць новы аб'ект з новым нязменныя прымітыўных сядзіць усярэдзіне.

Каб пытанні ўсё больш заблытанай, клас двайны затым падвойную працу, каб мець справу як з падвойным прымітываў і двайны абалонкай аб'ектаў. Напрыклад метады двайны маніпуляваць Падвойны аб'екты і статычныя метады для двайнога маніпуляваць двайны прымітываў. Гэтыя метады, натуральна, падобнымі, калі не ідэнтычныя імёны! Тая ж праблема ўзнікае для ўсіх іншых прымітыўных/клас пар, але большасць пачаткоўцаў, здаецца, спатыкнуцца спачатку

double d; /* double primitive */
Double dd; /* Double wrapper */
String g;

g = Double.toString( d ); /* double primitive */
g = dd.toString(); /* Double wrapper */
Глядзіце пераўтварэнні за дапамогу ў interconverting розных прымітываў і абгорткі.

ToString Blues

ToString вызначана на кожны аб'ект, каб дазволіць вам пераўтварыць яго ў радок. Аднак, String вы атрымаеце часта нічога падобнага і варта было чакаць.

Пры ўсталёўцы па змаўчанні ToString, вы проста атрымаеце імя класа і хэш-код аб'екта, які выглядае як трызненне, напрыклад, [C @ ad3ba4.

char[] c = { 'a' , 'b' , 'c'};

System.out.println( c.toString() );
will print out the address of c, not the characters that compose it. You must use newString ( char[] ) to convert a масіў сімвалаў ў радок.

Label.toString () не з'яўляецца псеўданімам для Label.getText (). Яна выведзе з рэзюмэ палёў Label так: java.awt.Label [label0, 0,0,0 x0, несапраўднымі, ALIGN = LEFT, тэкст = DEF]

Як жа тады вы пераўтварыць у String? З салянку з метадаў, якія могуць супернічаць французскіх дзеясловаў для парушэнняў.

Бяссільны злепкі

Злепкі, што разумныя людзі чакалі бы працу, з'яўляюцца несапраўднымі ў Java. Напрыклад, вы не можаце кінуць Int ў String або адваротны бок з (INT) "42" ці (String) 42. Замест гэтага вы павінны выкарыстоўваць Ходжа Подж метадаў interconvert асноўныя тыпы, імёны якіх больш хаатычнай, чым французскіх няправільных дзеясловаў. Гэта ганьба. Гэта такі беспарадак, што я напісаў аплет, завецца Converter для стварэння неабходнага кода пераўтварэнні.

Характарызуецца характар ??або колькасць?

сімвал можна разглядаць як пэўны сімвал ці без знака-разраднае цэлы лік 16. Гэтая двухсэнсоўнасць даганяе нас у заяве наступным чынам:
String x = "foo" + 's';
In Java version 1.6 or later, x is "foos". У пачатку Java версіі 1.2 гэта "foo115", але быў прызначаны на версію.

Васьмярковым

Я не бачыў васьмярковым выкарыстоўвалі з часоў Univac 1106 (за выключэннем права доступу да файлаў Unix), аднак Java правёў на C і C + + традыцыі. Любое лікавае літаральна з нуля прывесці на гэта лічыцца базай 8, васьмярковым. Асцярожна, праграмісты прывыклі выкарыстоўваць прывесці нулёў проста выраўноўвання лікаў у слупках.

Выпадак знікнення Канструктары

Пры вызначэнні канструктара, вы не павінны ўказваць тып вяртаецца значэння, нават калі ён паводзіць сябе так жа, як статычны метад завода, які вяртае аб'ект. Вы можаце нават не трэба вызначаць тып вяртаецца несапраўднымі. Лепш думаць аб канструктарах, як хацеў параметраў метадаў асобнікаў, якія працуюць на бягучы аб'ект.

Хоць канструктар падобны на статычны метад, які вяртае новы аб'ект, вы не можаце аб'явіць канструктар статычныя. Гэта не з'яўляецца статычным, так як ён працуе на канкрэтны аб'ект па змаўчанні. Гэта вызначана ў канструктар.

Калі любая з гэтых рэчаў, кампілятар думаеце, што ваш канструктар проста звычайным метадам. Вы будзеце збянтэжаныя скаргаў кампілятар аб тым, што вы не вызначылі падыходны канструктар, каб адпавядаць аргументы, якія вы дае.

Гэта можа дапамагчы, калі вы разумееце, што новы вылучае/стварае аб'ект і канструктар ініцыялізуе яго. Таму канструктара няма неабходнасці вяртання аб'екта.

Калі вы не дае ніякіх канструктараў на ўсіх, Java будзе аўтаматычна даваць Вам канструктар па змаўчанні

public MyClass()
   {
   super();

   }
\Аднак, калі вы амбіцыйныя і напісаць дадатковы канструктар, скажам так:
 прыватных MyClass (INT fudgicles)
{
. Гэтага fudgicles = fudgicles;

} 
Канструктар па змаўчанні знікне! Вы павінны затым прадставіць яму сябе ў відавочным выглядзе.

Хутчэй за ўсё, вы сутыкнецеся гэтай праблемы, калі вы бачыце наступнае паведамленне пра памылку:

нагрузка: com.mindprod.mypackage.MyApplet.class не можа быць створаны. java.lang.InstantiationException: COM/mindprod/MyPackage/MyApplet

У ангельскай мове гэта значыць, вам не хапае змаўчанні адчынены канструктар для вашага аплета. Глядзіце канструктар.

Адсутнічае Hex

У Java радкоў, вы больш не можаце сказаць "\ xf2", "\" ці \ V ", як вы можаце ў C + +. Да шчасця, "\ п", "\ R", "\\",\"і\" "усё яшчэ працуюць. Для кадавання кіраўнікоў сімвалаў без канкрэтных скарачэнняў вы павінны зараз выкарыстоўваць васьмярковым, напрыклад,"\012 "для перакладу радкі, раней "\ x0A". знакавых канстант Восьмиштырьковый павінна быць роўна 3 лічбы. Глядзіце літаральнае

Новыя Hex Unicode тэхніка "\ u003f" мае злавіць. Ён не прызначаны для кадавання сімвалаў кіравання. Яна ацэньваецца ў праход папярэдняй апрацоўкі і ператвараецца ў сімвал, то кампіляцыі кода. Калі, напрыклад, піша "\ u000A", гэта будзе аўтаматычна пералічаныя для:

 "
" 
Так як \ u000A канвертуецца ў сімвал новай радкі. Гэта дакладна не будзе працаваць для Cr і Lf. Гэта можа працаваць для некаторых іншых сімвалаў кіравання ў некаторых кампілятараў. Я прапаную выкарыстоўваць васьмярковым формы для бяспекі.

Math.sin

Кожны

double x = 90;

double y = sin( x );
double z = tan( x + PI );
І глядзіць і глядзіць на яго цікава, чаму яна не будзе працаваць. Вам трэба напісаць аб гэтым так:
// converting degrees to radians, manually.
static final double CONVERT_DEGREES_TO_RADIANS = Math.PI / 180;
double x = 90 * CONVERT_DEGREES_TO_RADIANS;

double y = Math.sin( x );
double z = Math.tan( x + Math.PI );
Ёсць тры месцы на паездку да:
  1. Пакет мат работ у радыянах, а не градусаў. 360 градусаў = 2? радыян.
  2. Вы павінны Math.sin замест звычайнага грэх, таму што грэх, COS, загар і г.д. статычных функцый. У параўнанні з іншымі мовамі вы можаце выкарыстоўваць, Java з'яўляецца прыдзірлівыя і шматслоўныя. Яна хоча "мат". нават калі няма канфлікту імёнаў з грахом функцыі ў пэўным класе іншыя, чым матэматыка або якой-небудзь пакет, акрамя java.lang. Java хоча, каб пазбегнуць нават магчымасці магчымага сутыкнення імя шляхам вы маеце права з Math.sin цяпер. Аналагічным чынам, вы павінны папярэднічаць ўсім статычнай функцыі і выклікі метадаў з імя класа.
  3. Вы павінны Math.PI замест звычайнага PI таму ПІ статычную канстанту. Аналагічным чынам, вы павінны папярэднічаць ўсім статычныя канстанты з імем класа.
  4. Java версіі 1.2 дадаў два метаду выгоды:
     //Убудаваны ў радыянах <-> метады градусаў.
    адкрытыя статычныя двайны toDegrees (двайны angleInRadians);
    
    адкрытыя статычныя двайны toRadians (двайны angleInDegrees); 
Math.sin (Double.PI)! = 0, так як Double.PI дакладна не роўна ірацыянальныя ліку «пі». Так Math.sin (Double.PI) не варта чакаць, што ў дакладнасці роўна грэх (PI). Аналагічным Math.cos (Math.toRadians (90)) не стукаць нуля небудзь.

Акрамя таго, кожны раз, калі вы з якая плавае кропкай разліку, вы губляеце трохі дакладнасці. Усё гэта стварае.

У Java 5.0 вам больш не трэба, як мат. У гэтым мат. Граху () да тых часоў, як вы дадаеце імпарту:

 імпарт статычных Java.. мат Lang; 

Дзе Beep?

Java не мае ўбудаванай ў набор гукаў. Вы можаце таксама вырабіць сігнал адправіць дынаміка ПК, пасылаючы сімвал BEL на кансоль.
 //Сігнал на дынамік кампутара, пасылаючы сімвал BEL на кансоль
Сістэма ".) З. Print ("\007;

Сістэма (.) З. Западліцо; 
Ён ігнаруе '\' у кансолі, хоць вы можаце выкарыстоўваць \ 007, каб атрымаць бел.

Вы можаце зрабіць просты гукавы сігнал з Інструментарый. GetDefaultToolkit (). Beep () . Я бачыў, пра тое, што гукавы сігнал не працуе належным чынам на некаторых платформах.

 //Сігнал праз кансоль
Сістэма ".) З. Print ("\007;
Сістэма (.) З. Западліцо;

//Сігнал праз інструментарый
Toolkit (. GetDefaultToolkit ()). Гукавы сігнал; 
Вы таксама можаце гуляць AU, WAV, MIDI і AIFF файлы з AudioClip.play.

Дзе каранёвай каталог?

Вы можаце паглядзець доўгі час праз java.io. * спрабуе знайсці каталог аперацый, перш чым вы знойдзеце іх хаваецца ў файле класа напрыклад, спіс каталогаў, каб даведацца файлы

File dir = new File( "C:\\" );

String[] files = dir.list();

won’t

File dir = new File( "C:\\." );

String[] files =dir.list();
Памятайце, што "\" у Java радкоў павінна быць напісана як "\\".

Гэта робіць чытанне радкоў, якія прадстаўляюць імёны файлаў у зман. Unix сістэмы выкарыстоўваюць "/" Шлях падзельнік замест "\". Макінтошы выкарыстоўваць ":" і ёсць цікавыя павароты як "::" на тэрмін да замест "/../" як у Unix. Каб напісаць незалежны ад платформы код, вы павінны выкарыстоўваць ўласцівасці file.separator сістэмы і path.separator, або выкарыстоўваць Файл метады, якія пабудаваныя імёнаў для вас ад часткі.

Тады

 Файл [] каранёў = Файл). ListRoots (; 

Для кожнай Прабелы

для: ярка выяўленая для кожнага з'яўляецца скарачэнне працяг на рэгулярнай для. Гэта дазваляе перабраць-итераторов, калекцыя S і масіваў з кароткім сінтаксісу. Аднак, ён не дазволіць вам перабору знакаў радкі або дазваляюць атрымліваць доступ да індэксу, як і вы з рэгулярнымі для, толькі значэння. Паглядзіце на наступны прыклад, каб убачыць, што я маю на ўвазе:

Unstoppable for

for ( long i=Long.MAX_VALUE -2; i<=Long.MAX_VALUE; i++ )

   {
   /*...*/
   }
Колькі раз, што для завесы выканаць? Пакуль вы не забіць працэс! Гэта будзе цыкл бясконца, таму што я ніколі не можа атрымаць больш, чым Long.MAX_VALUE спыніць цыкл. Ёсць аналагічныя праблемы з Integer.MAX_VALUE, Long.MIN_VALUE і Integer.MIN_VALUE. Вы прывыклі да думкі аб верхнім мяжы лагічнай пункту прыпынку, дзе кананічныя для завесы фактычна спыніцца на адным мінулым, што значэнне. Прычына завесы не спыняе з'яўляецца Java цэлалікавай арыфметыка дазваляе перапаўнення, як звычайна. Прычынай гэтага з'яўляецца большасць абсталявання паводзіць сябе такім чынам і многае трохі дробязны будзе занадта складанай, калі перапаўненне кінуў выключэння. Вы можаце звяртацца выяўленне лікаў становіцца занадта вялікім з сцвярджаюць, які ловіць праблемы задоўга да таго, яны блізкія да перапаўнення 32 або 64 біта.

Сюрпрызы верхні рэгістр

Зірніце на крыніцу java.lang.String.toUpperCase (). Можна было б чакаць, каб яно ўтрымлівала

if ( 'a' <= theChar && theChar <= 'z' ) theChar -= ('a' -'A' );
Аднак, вы адкрыеце для сябе код даволі развіты. Напрыклад, ён правярае, ці з'яўляецца бягучая лакаль турэцкіх тэлефанаваць спецыяльны код, каб справіцца з dotless I. Гэта тэсты для нямецкіх СС і пераўтворыць яго ў пару літар "СС"! Калі вы працуеце толькі з ангельскай мовай, вы можаце згарнуць уласны больш рацыянальны варыянт. Калі ўзяць радок у ніжні рэгістр затым назад у верхні рэгістр затым назад у ніжні рэгістр, вы не абавязкова канчатковым выніку, калі вы пачалі.

String.substring

У іншых мовах, для вымання падрадка, вы даеце зрушэнне дзе радок пачынаецца і даўжыня ў сымбалях. У Java, вы дае два нуля зрушэння. Першы паказвае на пачатак радка, як і варта было чакаць, і

"abcdefg".substring( 3, 5 ) gives "de".

"abcdefg".substring( 3, 7 ) gives "defg".
"abcdefg".substring( 3, 8 ) gives StringIndexOutOfBoundsException.

Калі паказаць зрушэння, якія знаходзяцца па-за абалонкі радкі, вы не атрымаеце усечаных або пусты радок; вы падымае StringIndexOutOfBoundsException. Адзін са спосабаў памятаю, як яна працуе, што вы паказаць першы знак ўключыць і першы знак выключыць. Але не зусім. Вы маеце права быць ледзь мінулым канца.

"emptiness".substring( 9 )
returns "" (an empty string)
"emptiness".substring( 10 )
дае StringIndexOutOfBoundsException

Чаму гэта так?

Існуе яшчэ адзін погляд на індэксаванне, што адпавядае паводзінам Java ў больш натуральным спосабам. Індэкс не паказваецца знак у радку, ён вызначае становішча паміж знакаў радкі, пачынаючы з 0 і заканчваючы на даўжыню радка. Напрыклад, "Яблык" мае індэксацыі наступным чынам:
(0) A (1) P (2) P (3) L (4) E (5)

Then:

s = "APPLE".substring( 1, 4 ); // gives "PPL".

s = "APPLE".substring( 3, 3 ); // gives "".
s = "APPLE".substring( 0, 5 ); // gives "APPLE".
Сцеражыцеся выкарыстання падрадок толькі з адным аргументам.
 String хвост = х). Падрадок (endindex; 

атрымлівае вас хвасце радкі, пачынаючы з endindex. Гэта не вам пачатак

 = Х. Кіраўнік падрадок (0, даўжыня); 
атрымлівае вас першая частка радка, першыя літары даўжыні.

Непараўнальны NaN

Пры дзяленні на нуль з падвойным, атрымаць квадратны корань з адмоўнага ліку, перапаўненне максімальна прадстаўляльная г.д. значэнне вынік магічнае лік называецца Double.NaN, Double.POSITIVE_INFINITY або Double.NEGATIVE_INFINITY. Вы

 калі (Double. IsNaN (D)) 

або з Double. IsInfinite . Вы не можаце праверыць

 калі  == двайны. NaN) 

Паколькі Існуюць два розных густаў НАН, двайны. POSITIVE_INFINITY і Double. NEGATIVE_INFINITY Вы не можаце непасрэдна параўнаць == двайны. NAN для праверкі НАН. Аднак, вы можаце адразу параўнаць == двайны;. НАН Аднак, вы можаце выкарыстоўваць Double. IsNaN або == параўнаць з падвойным. POSITIVE_INFINITY. Існуе адпаведны паплавок. NaN і Float. IsNaN Тэорыя прыняцця NaN не роўны самому сабе дазваляе хутка і брудны спосаб для праверкі разлікаў будзе неабгрунтаванай.

if ( result != result )
   {
   System.out.println( "oops" );

   
   } 

StringBuffer.equals

Беражыся

Праблема ў тым, StringBuffer. Роўная правярае дзве спасылкі паказваюць на той жа StringBuffer, тое, што вы амаль ніколі не хочуць рабіць. StringBuilder мае той жа Гоча.

valueOf і нуль

int[] intArray = null;
String.valueOf( intArray ); // produces the String "null"

char[] charArray = null;
String.valueOf( charArray ); // throws NullPointerException

Заключны супраць Const

Java мае ключавое канчатковым і C + + мае ключавое слова сопзЬ. Яны падобныя, але не трапляюць у пастку, думаючы, яны ідэнтычныя. Аб'ява зменнай фінал прадухілення значэнне гэтай зменнай ад змен пасля ініцыялізацыі. Аднак, калі гэтая пераменная з'яўляецца спасылкай на аб'ект, гэта не абавязкова будзе прадухіліць ў розных галінах, што аб'ект ад змен, напрыклад,
 Апошняе, што рэч = новая рэч (7);
рэч = otherThing // генеруе памылку кампіляцыі

рэч;. SetSize (10) //OK
рэч;. абхапілі = 6 //OK 
Гэта таксама адносіцца да параметраў абвешчаны канчатковым.

Перапаўненне

Java з'яўляецца кавалерам аб перапаўненні. Ёсць не падчас кампіляцыі папярэджанняў ці выключэнняў падчас выканання, каб вы ведаеце, калі вашыя разлікі сталі занадта вялікімі, каб захоўваць яшчэ ў Int ці доўга. Існуе ніякіх папярэджанняў для паплаўка ці двайны перапаўнення небудзь. Адным з месцаў, вы часта атрымліваеце прыбіў, калі некаторыя разлікі ажыццяўляюцца ў Int, часткі высокага парадку ўсечанай, затым прызначаны на доўга.

Глядзець

у BigDecimal IBM і Arcimath BigDecimal маюць прыстасаванні для выяўлення перапаўнення і генерацыі выключэння. Але вы можаце самастойна з такі код ў стандартны Java.

or

Калі вы ведаеце, абодва значэння дадатныя, вы можаце выкарыстоўваць простую праверку перапаўнення. Вы можаце праверыць, калі сума менш 0 або менш, чым адзін з двух аперанд. Я не ўпэўнены, што ловіць усё перапаўнення, аднак.

Арыфметыку з якая плавае кропкай выкарыстоўвае IEEE памылкі распаўсюджваецца схеме, аналагічнай выкарыстанай у табліцу, каб распаўсюджвацца несапраўднымі сцягі значэння ў ячэйкі, якія залежаць ад недапушчальных значэнняў. У Java, хоць няма перапаўнення перапыненняў або паведамлення, ёсць добрыя шанцы, вы ў рэшце рэшт даведаліся пра памылка перапаўнення, калі вы бачыце java.lang.Double.POSITIVE_INFINITY, java.lang.Double.NEGATIVE_INFINITY або java.lang. Double.NaN з'яўляецца ў адным з вашых падвойных пераменных. Вы не можаце выкарыстоўваць == для праверкі NaN, вы павінны выкарыстоўваць java.lang.Double.isNan ().

BigDecimal Параўнанне

==, BigDecimal. Гэтак сама і BigDecimal. CompareTo () == 0 ўсё даюць розныя вынікі.

Змена супраць Ценяў

Што адбываецца, калі вы паўторна метад або імя зменнай у падклас? Гэта залежыць. Ёсць чатыры выпадкі:
  1. статычнага метаду
  2. Метад асобніка
  3. статычная пераменная
  4. зменнай асобніка
Вы ўспадкуюць суперкласса версію або атрымаць падклас версіі? Усё гэта вельмі дзіўна, я прапаную вам выканаць некаторыя эксперыменты. Вось маленькая праграма, я напісаў адкрыць для сябе розныя зацяненні і пераазначэнне паводзін:
Мой агульны савет ніколі не цень пераменных. Існуе не трэба для гэтага. Гэта толькі прыводзіць да блытаніны. У выніку:

"Зламаная" setLocation, SetSize, setBackground, setForeground

Людзі часта скардзяцца, што яны не могуць атрымаць setLocation, SetSize, SetBounds, setBackground або setForeground на працу. Праблема, як правіла, гэта што-то стварае іх і пераазначэнне настройкі: Вінаватыя ўключаюць у сябе:
  1. Макет менеджэраў. Яны памеру () і перамяшчэння () (састарэлая назва метаду) на ўтрыманне кожнага кантэйнера. Толькі нулявой менеджэр макет будзе пакінуць свае памеры без змен.
  2. Згенераваны код у Visual Cafe зробіць крок () і паказаць () (састарэлыя назвы) у пераазначэнне Show () метад.
  3. Ваш уласны код, выкарыстоўваючы састарэлыя імёны, як рухацца () ці змяніць памер ().

Бяззнакавыя байтаў

Назад, калі Зямля была яшчэ расплаўленай, калі сімвалы засталіся толькі 7 біт, хто-то думаў, што гэта будзе добрая ідэя, калі знакі былі падпісаныя. Гэта выклікала раскол у свеце C, калі 8-бітныя сімвалы пазней з'явіўся. Java дадаў бяззнакавыя 16-бітны Unicode сімвалы, але вырашылі падтрымаць толькі падпісаныя 8-бітавых знакаў, вядомы як байт. Магчыма, дызайнеры Java, хацеў заахвочванне міграцыі ў Юнікод шляхам апрацоўкі бяззнакавыя байтаў няёмка. У любым выпадку, вы часцей за ўсё хочуць бяззнакавыя 8-бітныя сімвалы, не падпісаны.

int i1 = b2 & 0xff;
byte b2 = (byte)( b2 + 1 );

byte b3 = b2;

Модуль

У Java вы бярэце з астатняй% аператара. У Java, знакі астатак варта дывідэндаў, а не дзельнік. Java Аддзел эўклідавай уласнасці. Калі трэба памножыць фактар ??на дзельнік і дадаць астатнюю вы вернецеся да дывідэндах. Java Аддзел ўсечанага дывізіі.

Аддзел павярховым тое, што вы звычайна хочуць, калі спрабуюць высветліць, якія бен належыць элемент у якой Вы можаце

Для вылічэння, колькі фіксаванага памеру бункераў неабходна ўтрымліваць N элементаў, вы хочаце ceiled падзелу, таксама вядомы як пакрытыя фактар. Вы можаце вылічыць пакрытыя фактар, як:

Inconsistent Signs
Signs Division Modulus
+ + +7/+4=+1 +7%+4=+3
- + -7/+4=-1 -7%+4=-3
+ - +7/-4=-1 +7%-4=+3
- - -7/-4=+1 -7%-4=-3
У мяне ёсць агульнае правіла, каб пазбегнуць напісання кода, які залежыць ад чаканых знак модуля. Часта крыніцай памылак, паколькі людзі тэсціравання ёсць свае ўласныя ідэі аб тым, як адказы павінны быць. Напрыклад Microsoft JIT дае няправільныя знакі нават для падзелу, але перакладчык дае правільныя.

Статычныя Initialisers

Вы павінны прыкласці любыя ініцыялізацыі код для статычных (клас) зменных ўнутры сэндвіч наступным чынам:
static { calcPriceTab();}
Навічкі проста прытрымлівацца такой код у любым месцы ўнутры класа {} сэндвіч і збянтэжаныя якія ўводзяць у зман паведамленні аб памылках.

Парадак вашых зменных, якія статычна ініцыялізуецца пытанні. Лічыце, што гэта маленькая праграма:

Выхад з Java 1.4.1 была не памылка на этапе кампіляцыі і 61 0 61, YMMV.

Парадак гэтых трох статычных фінал мае вырашальнае значэнне для вынікаў! Вы павінны змясціць іх у парадку, вы хочаце зрабіць разлікі. Java не з'яўляецца элегантным, як табліцу, каб зрабіць натуральны recalcs для Вас. Гэта апавяшчэнне і альбо ручкі або адхіліць такія спасылкі наперад, калі толькі литералы і простых зменных ўдзельнічаюць, але як толькі вы робіце рэчы ўнутры метадаў, яна кідае свае рукі і кажа аб вашай ўласнай галаве і быць.

Асобнік Initialisers

У вас ёсць магчымасць ініцыялізацыі зменнай асобніка ў:
  1. Дэкларацыя
  2. Канструктар
  3. Блок напрыклад Инициализатор

Перавага паставіўшы яго на дэкларацыі з'яўляецца тое, што вам трэба паказаць толькі адзін раз, не адзін раз для кожнага канструктара. Гэта азначае, што менш верагоднасць памылкі, калі яе значэнне ўсё змянілася. Іншыя бяспечныя падыход паставіць усё ініцыялізацыі кода ў адным метадзе або адзін канструктар і ўсё канструктары называюць яго.

Канструктар ініцыялізацыі

Для таго каб поля ініцыялізуюцца вельмі тонка.
Канструктар падрабязней

Аднак, ёсць адна асабліва складаная праблема з ініцыялізацыяй парадку. Увогуле, вы павінны пазбягаць выкліку любога не канчатковыя метады ў канструктар. Праблема ў тым, напрыклад initialisers/пераменная ініцыялізацыі ў вытворных класе ажыццяўляецца пасля канструктара базавага класа. Гэта можа выклікаць праблемы, калі базавы канструктар класа выклікае метад паліморфным, так як гэты метад будзе мяркуючы яго вытворныя палёў класа ўсе былі ініцыялізуецца, калі яны гэтага не зрабілі.

Так базе канструктараў класа можна смела называць прыватнымі або канчатковы метады базавага класа ўмове, што гэтыя метады, прама ці ўскосна выклікаць толькі прыватнымі або канчатковы метады базавага класа. Пры выкліку метадаў у канструктару паліморфным, кампілятар не будзе спыніць або папярэдзіць вас пра ініцыялізацыі пасткі чакаюць.

Злепкі

Java з'яўляецца строга типизированным мовай. Вы не толькі павінны ведаць, якой тып кожнага з вашых зменных былі абвешчаныя, вы таксама павінны сачыць за тып аб'екта, кожны дадзены момант паказвае, што можа быць падкласаў заявіў класа.

Ёсць чатыры віды ролях:

  1. пашырэнне

    byte b = -42;
    int i = (int)b;
    Гэта прывядзенне безвыніковым, хоць вы можаце выкарыстоўваць кінута як дакументацыя дапамогі. Яна робіць некаторыя пераўтварэнні працы - знакавая пашырэнне.
  2. звужэнне

     Int I = - 16411;
    байт = B (б) я; 

    Гэты стыль літых на самой справе могуць рабіць некаторыя рэальныя працы пераўтварэнні - абнулення старэйшых бітаў.

  3. да суперкласса

     Сабака МуОод = (сабака) aDalmatian; 
    Гэта прывядзенне безвыніковым, хоць вы можаце выкарыстоўваць выпадку, як дакументацыя дапамогі. Усе далмацін аўтаматычна ўсе сабакі поля, так што гэта ліццё не мае часу выканання накладныя выдаткі.
  4. да падклас

     Далматин myDalmatian = (далматин) aDog; 
    Падчас выканання гэтага літой на самай справе правярае, што aDog сапраўды ўжо далматина, і павышае ClassCastException, калі гэта не так. Гэта не робіць любыя спробы пераўтварыць сабаку далматин.
  5. Злепкі з абстрактныя класы і інтэрфейсы працуюць так жа, як класы.
Дык дзе ж памылкі?

Няяўныя злепкі

Пераўтварэнні і звесткі аб развіцці адбывацца як пры відавочным прасіць іх, а часам аўтаматычна.
  1. Аўтаматычнае прысваенне Пераўтварэнне тыпу пераўтворыць выраз да тыпу зменнай (напрыклад, кароткае значэнне = 26). Гэты тып пераўтварэнні дапускаецца пры пераўтварэнні з тыпу таго ж тыпу (пасведчанне пераўтварэнне), пры выкананні пашыраюць пераўтварэнне, або пры выкананні звужэнне пераўтварэнні якіх прызначае Int на байт, кароткія, або сімвал зменнай, дзе Int прадстаўляльная шляхам (байт, кароткі, ці знак) зменнай. Звярніце ўвагу, што гэтая форма канверсія адбываецца толькі ў заданні, якія выключаюць выключэння па азначэнні.
  2. Аўтаматычная лікавае пашырэнне гомогенатах аперанд, каб аперацыі (напрыклад, 1.0f + 2.0 выкліча 1.0f быць падвышаны да двайны).
  3. Аўтаматычная Method Invocation канверсія адбываецца пры пераходзе аргументаў падчас выкліку метаду (напрыклад, выклікам MethodA (45) па метадзе вызначаецца як MethodA (доўгае значэнне)). Акрамя забароны няяўнай звужэнне цэлалікавых канстанты, гэтая форма паводзінаў пераўтварэнні з'яўляецца ідэнтычнай аўтаматычнага пераўтварэння прызначэння. Звярніце ўвагу, што гэтая форма канверсія адбываецца толькі тады, калі аргумент тыпу перадаецца ў метад можа быць аўтаматычна ператвораны ў названых у сігнатуру метаду такім чынам, каб выключыць магчымасць выключэння па азначэнні.
  4. Аўтаматычная Пераўтварэнне радкоў дазваляе любы тып павінны быць ператвораны ў тып String. Гэта адбываецца, калі "+" Радок аб'яднання выкарыстоўваецца аператар (напрыклад, String resultString = "Адказ:" + вынік, дзе вынік можа быць любога тыпу)

Канкатэнацыі

Java выкарыстоўваецца аператар "+" азначае, як таго і канкатэнацыі. Парсер могуць адназначна высветліць, якія вашыя намеры ад кантэксту, але людзі могуць так лёгка абдурыць. Напрыклад:

 Сістэма у.) З. Println ("X + Y + X +;

з сістэмы.. println (X + Y + "X + Y"); 

Якія + складанне? Якія аб'яднання?

Тое, як вы часцей за ўсё патрапіць з'яўляецца код, падобны гэтаму, дзе апошнія + разглядаецца як канкатэнацыі.

 Сістэма 1.) З. Println ("значэнне:" + V +; 

Аператар канкатэнацыі валодае магічнай сілай, якое дазваляе няяўна прымушаць Int ў String шляхам аўтаматычнага выкліку
статычную радок цэлае. ToString (INT)
метад, аднак, як ні дзіўна, вы не можаце зрабіць тое ж самае відавочна з (String) акцёраў.

System.out.println( 'A' );

System.out.println( 'A' + 'B' );
Вы маглі б чакаць naiively: AB, ці, магчыма, 65 131, аднак, адказ: 131.

Праблема ў тым, дызайн памылкай у Java выкарыстання + для абазначэння як таго і канкатэнацыі. Даданне таксама спрыяе Int, які println адлюстроўваецца інакш, чым знак.

Я сапраўды жадаю гэта выпраўлена. Аб'яднанне павінна атрымаць новы сімвал аператара і выкарыстання + для аб'яднання павінна быць састарэлымі. Цяперашняя схема прыводзіць да код занадта лёгка няправільна. + З Int можа азначаць альбо таго або аб'яднання. Прыняцце рашэння якой залежыць занадта шмат на тонкія ключы кантэксце.

addChangeListener

Сімптомы гэтага Гоча атрымліваеце два ChangeEvent S спрацоўвае, дзе можна чакаць толькі адзін, ці з выкарыстаннем removeChangeListener і падзеі працягваюць прыбываць. Загваздка ў тым, вы павінны выклікаць addChangeListener толькі адзін раз. Калі вы называеце гэта ў два разы з тым жа дэлегаты, вы стварылі два прымача з кожнага атрымліваць копію кожнага ChangeEvent. AddChangeListener дадае другі ChangeListener нават калі ён ужо дадаў. Аналагічным чынам, removeChangeListener толькі выдаляе першы знойдзены ChangeListener ён знаходзіць, а не дубліруе таксама. Гэта адносіцца да ўсіх тыпаў слухач.

М у O utput L ooks L Айк T яго

Ёсць 10 распаўсюджаных тыпаў апрацоўкі знакаў у Java

Дзесяць тыпаў знакаў Апрацоўка
Тып змяняныя? памер у бітах падпісаў? Апісанне
String няўхільны 16 непадпісаны Unicode
StringBuffer Змяняныя як у вартасным, і памер 16 непадпісаны Unicode
StringBuilder Змяняныя як у вартасным, і памер. Хутчэй, чым StringBuffer, але толькі ў Java версіі 1.5 або больш позняй версіі 16 непадпісаны Unicode
FastCat Змяняныя як у вартасным, і памер. Хутчэй, чым калі StringBuilder аб'яднання радкоў, а не сімвалы. Лягчэй для ацэнкі памеру. 16 непадпісаны Unicode
сімвал змяняныя значэння 16 непадпісаны індывідуальны характар ??Unicode.
Характар няўхільны 16 непадпісаны Юнікод аб'екта.
сімвал [] змяняныя значэння 16 непадпісаны масіў сімвалаў Unicode.
байт змяняныя значэння 8 падпісаны асобных ASCII сімвалаў.
Байт няўхільны 8 падпісаны ASCII-сімвал аб'екта.
Byte [] змяняныя значэння 8 падпісаны масіў сімвалаў ASCII.
UTF няўхільны 8/16 непадпісаны 16-біт, 7-бітныя сімвалы, многобайтовые коды для 16-бітных знакаў з высокім біт.
Асабліва, калі вы робіце I/O. Вы павінны быць вельмі ясна, ці будзе ў вас ёсць 8 ці 16-бітавых знакаў ўнутранае і 8 ці 16-бітавых знакаў вонкава. Некаторыя I/O метадаў пераўтварэння, некаторыя няма. Hex-прагляднік файлаў дапаможа вам адсачыць такія праблемы. ASCII сімвалаў пры пераўтварэнні ў Юнікод мае высокага парадку 0 байт дапісваюць ў пачатак, так як усе Java ўводу/вываду ад старэйшага да малодшага.

Финализаторы Не деструкторы

C + + праграмістаў, як правіла, думаюць, што завяршыць () метад эквівалентны деструктор. Гэта не праўда, па двух прычынах:
  1. Існуе ніякай гарантыі, што завяршэння ніколі не будзе выкліканы.
  2. Финализаторы аўтаматычна не распаўсюджваюцца па ланцужку спадчыну як деструкторы. У прыватнасці, вы павінны ўручную выклікаць super.finalize () з усіх вашых завяршыць метадамі. Існуе ніякай гарантыі, аб парадку выкліку завяршэння.
Існуюць дзве сістэмы метадаў, якія вы павінны ведаць:
  1. System.runFinalization () выконваецца завяршэнне метады любых аб'ектаў да завяршэння.
  2. System.runFinalizersOnExit (лагічнае значэнне) рэкамендуецца. Гэта выклікае ўсё завяршэння метадаў, якія будуць выклікацца перад выхадам. Гэты метад па сваёй сутнасці небяспечна. Гэта можа прывесці да финализаторы называюць на жывыя аб'екты ў той час як іншыя патокі адначасова маніпулявання гэтымі аб'ектамі, у выніку непрадказальнага паводзін або тупік.

Нарэшце

Нарэшце можа прывесці да блытаніны. Нарэшце, ключавое слова ў адказ на Java C + + деструкторы. У C + +, калі аўтаматычная аб'екты выходзяць з сферы (нават у выніку кінулі выключэнне), аб'ектаў деструкторы выклікаюцца ў дакладна вызначаных мэтах. Java мае збор смецця і не деструкторы, так што неабходна нейкім чынам гарантаваць, што некаторыя рэчы перад выхадам з рамкі. Нарэшце, дазваляе дасягнуць гэтага, але калі вы пакладзеце пэўныя віды справаздачнасці ў рэшце рэшт блокаў, вы можаце заблытаць сябе. Наступныя

Акрамя таго, паводзіны выключэнняў ўнутры блокаў, нарэшце, не з'яўляецца відавочным.

Ніцевыя

Тэма бяспекі underspecified, у прыватнасці:
  1. Наступствы завяршэння на паралельных праграм. У нд В.М., ёсць паток смецця, які адказвае за вызваленне невыкарыстоўваемых аб'ектаў і заклікаючы іх завяршэння. Калі ваш завяршэння званкоў сінхранізаваных метадаў, вы можаце сутыкнуцца з вельмі складана адладжваць тупікоў.
  2. Калі рэалізацыя метаду клон () з інтэрфейсу Cloneable быць ніцевыя ці не?
  3. Эмпірычнае правіла: ніколі не лічыць, што JDK аб'ектаў, з'яўляюцца ніцевыя. Не думаю: "О, я ўпэўнены, я здагадваюся, ажыццяўлення, і ён павінен быць ніцевыя." Напрыклад, java.util.SimpleDateFormat не ніцевыя, так што рэчы, як гэта можа выклікаць дзіўныя памылкі фарматавання

  4. Swing кампаненты не з'яўляюцца струменевай-арыентаванымі. Вы павінны выкарыстоўваць javax.swing.SwingUtilities.invokeLater ()/invokeAndWait () або EventQueue. InvokeLater. У любы код, які можна было б зрабіць называецца паток, акрамя асноўны струмень дыспетчарызацыі падзей. Гэта выплывае часта ў напісанні ўласных ListModels і TreeModels якія адказваюць нелокальных або не-GUI падзей.
  5. java.util.Hashtable і java.util.Vector два прыкладу JDK аб'ектаў, кожны метад з'яўляецца сінхранізаваныя. Гэта накладвае вялікую кошт выканання на прыкладанні, якія перабору гэтых структур. Калі вы не выкарыстоўваеце тэмы, аддаюць перавагу java.util.HashMap і java.util.ArrayList адпаведна. Калі вы выкарыстоўваеце Java версіі 1.6 або больш позняй версіі , Ён можа заплаціць, каб пажыраць Hashtable код і выдаліць сінхранізацыі.
  6. Thread.sleep (5000) мяркуецца сну на працягу 5 секунд. Аднак, калі хто-то змены сістэмнага часу, вы можаце спаць на працягу вельмі доўгага часу ці няма часу на ўсё. OS запісу часу абуджэння ў абсалютнай форме, а не адносныя.
  7. Тэма планаванне не гарантуецца крузе. Задача можа цалкам свіней працэсара за кошт нітак аднолькавы прыярытэт. Вы можаце выкарыстоўваць Thread.yield (), каб мець сумленне. Вы можаце выкарыстоўваць Thread.setPriority (Thread.NORM_PRIORITY-1) у ніжняй ніткі прыярытэтных. У аплеты неабходна бяспекі дазвол на яшчэ ніжэй прыярытэт патоку.

лімон java.math.BigDecimal

BigDecimal забяспечвае нязменнае адвольнай дакладнасці падпісаў дзесятковых лікаў. BigDecimal складаецца з адвольнай дакладнасці цэлае немасштабированный значэння (2-BigInteger дадаткам да двух зменнай даўжыні масіва байтаў) і неадмоўных 32-разраднае цэлы лік маштабу, які ўяўляе сабой колькасць лічбаў справа ад дзесятковай кропкі.

Для большай эфектыўнасці, часта можна выкарыстоўваць доўгія або INT, і сачыць за маштабаванне сябе, і ўстаўка дэкаратыўных дзесятковай кропкі на выхадзе.

BigDecimal з'яўляецца пародыяй і заслугоўвае маліны як дата. Карацей кажучы, гэта вельмі павольны працэс, цяжка выкарыстоўваць, яна выкарыстоўвае ўласныя метады, і ён ціха падае ўважаецца лічбаў у працэсе пераўтварэння.

Акрамя таго, java.text. DecimalFormat. Разбору вяртае альбо доўгі або Double. Існуе няма ўбудаванага спосабу вызначыць карыстацкі фармат нумары BigDecimal або BigInteger аб'ектаў.

На шчасце, IBM зрабіла даступнымі яго замены прапануецца для свайго класа Сонца, якія ў 23 разы хутчэй, менш, не выкарыстоўвае ўласныя метады, і рэалізуе стандартны ANSI X3.274 плавае арыфметыкі. Для спектраў гл.: IBM, дзесятковай арыфметыкі для Java і AlphaWorks. Дырк Bosmans рэалізаваны спектр IBM як ArciMath. Іншая рэалізацыя PSPDec.

java.awt.Graphics.drawRect

 Java. AWT. Графікі. DrawRect (INT X, Y Int, Int шырыня, вышыня Int) 

Малюе прастакутнік адзін піксель больш названай шырыні і вышыні. Мне сказалі, калі вы разумееце, абстрактная мадэль малявання AWT выкарыстоўвае, аказваецца, гэты дадатковы піксель наўмысных і непазбежнымі. Абгрунтоўваецца тым, што вы паказваеце шлях ідэалізаваны акно звяртаецца з бясконца тонкімі лініямі, і ручка вісіць ўніз і направа, па меншай меры адзін піксель таўшчынёй.

java.awt.Graphics.drawString

Уся графіка працэдур чакаць х, у прадстаўляць верхнім левым куце абмежавальнай рамкі. Аднак для графікі. DrawString () X, Y ставіцца да з базавым (які адрозніваецца яшчэ раз ад левым ніжнім куце). Гэта супярэчнасць з'яўляецца традыцыйнай у распрацоўцы пакетаў. Вы павінны

 г). DrawString ("Hello World", 0, getFontMetrics (GetFont () (). getAscent); 

GridBagLayout

Кожны раз, калі вы карыстаецеся любы менеджэр кампаноўкі, акрамя NULL, гэта будзе вырашаць памераў і размяшчэння кампанентаў. Ваш setLocation (), SetBounds () і SetSize () выклікае ўсё будзе перавызначаны. Некаторыя спосабы можна атрымаць больш дакладнага кіравання з'яўляюцца: GridBagLayout часам вядзе сябе дзіўна, ствараючы дзіўна асіметрычнага макетаў. Праблема, як правіла, узыходзяць да спробе пакласці двух кампанентаў у той жа вочку сеткі. Вы не будзеце атрымліваць паведамленне пра памылку, калі вы робіце гэта.

GridBagLayout будзе генераваць Гуфи макеты, калі кампаненты забяспечваюць некарэктныя нумары для мінімальнага і патрэбны памер. Напрыклад TextField S не прымаць пад увагу SetColumns або памеру бягучага шрыфта. Усё, што вы можаце зрабіць, гэта выдумкі выкарыстаннем ipadx і ipady параметраў, каб раздуць мінімальнага памеру.

GridBayLayout не пярэчыць, калі ў вас ёсць радкі або слупкі з чым у ім. Гэта зойме не займаюць месцы. Вы маглі б пакінуць некалькі пустых радкоў і слупкоў у макеты для будучага пашырэння.

weightx і важкі кіравання, дзе ідзе дадатковае прастору, калі кантэйнер пашыраны. Думайце пра іх як пра працэнтах, якія не павінны дадаць да 100%. Яны аўтаматычна нармалізаваная. Каб высветліць, якія калонкі павінны атрымаць большую частку прасторы, GridBagLayout разглядае кожнага кампанента ў калонцы, і глядзіць на яго weightx. Гэта эканоміць найбуйнейшых weightx ўсіх кампанентаў у гэтым слупку, як вага для ўсяго слупка. Гэта не сярэдні іх, ці дадаць іх. Тады прапарцыйна прызначае дадатковае прастору на аснове слупка вагі. Кампаненты з вялікай вага не абавязкова расці, толькі слупок, кампаненты цалі дае роўныя, але ненулявой вага калоны імкнецца выраўнаваць іх памеры.

GridBagLayout робіць тое ж самае вылучэння дадатковага прасторы для радкоў з дапамогай важкіх.

Ўстаўкі (зверху, злева, знізу, справа) можа быць выкарыстаны для стварэння рамкі вакол кампанента. Чатыры лічбы вымяраюцца ў піксэлях.

Калі вы жадаеце выправіць памер некаторых элементаў, вы павінны выкарыстоўваць усе тры метаду: setMinimumSize, setMaxiumSize і setPreferredSize.

Пераканайцеся, што вы некаторы ненулявое х і ў вагаў у вашу GridBag. У адваротным выпадку, калі Вы сціскаеце кадра ўніз занадта малы кампаненты будуць дзейнічаць, як быццам яны бясконцай прасторы і будзе ўцякаць вар'яцка закадравы з правага боку.

Калі вы выкарыстоўваеце GridBagConstraints.BOTH, прымушаючы запоўніць, то яна перакрые любую setMaximumSize вы, магчыма, указаны на вашай панэлі.

Null Макет

Можна апрацоўваць ўручную макет з нулявым менеджэр макета. Для абсалютнай пазіцыянавання, у тэорыі ўсё, што вам трэба зрабіць, гэта Container.setLayout (нуль), і становішча кампанентаў з Component.setLocation (х, у). Аднак, калі вы гэта зробіце, вы часта глядзіце на пусты экран. Вось некаторыя рэчы, каб праверыць. Як ні дзіўна, гэта можа быць прасцей напісаць свой ??уласны LayoutManager каб зрабіць вашу пазіцыянавання. Перавагі напісання карыстацкага макета з'яўляюцца: Для простых LayoutManager або LayoutManager2, многія з метадаў можа быць соску.

Састарэлыя Blues

З Java версіі 1.6 або больш позняй версіі , Sun прынёс больш для наймення розных метадаў, у прыватнасці ў AWT. Старыя назвы па-ранейшаму падтрымліваюцца, але састарэлая (рэкамендуецца ад выкарыстання аж да поўнага выдалення). Састарэлыя імёны не псеўданімы кампілятар перакладае на новыя імёны. Яны з'яўляюцца паўнавартаснай метады самі па сабе. Я задаваўся пытаннем, чаму такіх вытворцаў, як Сонца і Symantec былі настолькі не хочуць адмаўляцца ад старой назвы цалкам і поўнасцю пераўтварыць у новую схему. Я знайшоў, чаму.

setVisible () выклікае састарэлым Show (), адваротнае, што вы маглі чакаць. Можна падумаць, састарэлым метадам павінны несці пакаранне хуткасць іншага ўзроўня ўскосна. Але што адбудзецца, калі вы пішаце новую setVisible () выкарыстоўваецца для пераазначэння аднаго з убудаваных у іх. Карыстальнікі арыгінальнае шоу () метад не будуць закрануты. Яны будуць працягваць выкарыстоўваць стары код. Толькі тыя, хто непасрэдна выклікаць setVisible () будзе выкарыстоўваць свой ??новы парадак. Зараз, разгледзім, што адбудзецца, калі вы пішаце новую састарэлым Show () метад для пераазначэння аднаго з убудаваных у іх. Усё працуе правільна, кожны будзе выкарыстоўваць свой новы метад. Вы, такім чынам, затрымаўся напісання новых састарэлымі метадамі, калі вы хочаце, каб ваш код працаваў карэктна.

Скажам AWT былі перапрацаваныя так, што замест Show () завецца setVisible (). Тады стары код, які выкарыстаў забароненыя метады раптам перастаюць працаваць.

Гэтая праблема носіць агульны характар ??і распаўсюджваецца на ўсе састарэлыя метады. Будзем спадзявацца, Сонца будзе хутчэй пазбавіцца ад састарэлых метадаў цалкам, то гэтая праблема знікне. Большасць састарэлых імёнаў толькі імя змены, каб адпавядаць JavaBeans атрымаць/устанавіць канвенцый. Такія састарэлых могуць быць разгледжаны як чыста псеўданімы перакладу на новыя імёны ў кампілятар, і пакончыць са старымі класамі цалкам. Разам з тым, што выкліча палітычныя праблемы JDK 1.0.2 код больш не працуе пад Java версіі 1.6 або больш позняй версіі без перакампілявання або якой-небудзь працэс перакладу. Вы не маглі б мець код, які будзе працаваць як пад JDK 1,02 і 1,1. Мы павінны падтрымліваць працэс пераводу ў JVM, каб стары код аўтаматычна выкарыстоўваць новыя імёны. Сонца вельмі неахвотна ідуць на любыя змены ў JVM.

JDK 1.0.2 працэдурах апрацоўкі падзей і састарэлым. Гэта крыху больш працы, каб канвертаваць гэтыя. Яны не маглі быць апрацаваныя з дапамогай простага псеўданіма.

java.io.BufferedReader і BufferedInputStream

int BufferedInputStream.read( byte[] m, int offset, int len )
рэкламуецца блакаваць да некаторых ўваходных даступная. Яна вяртае колькасць лічаных байтаў або -1 для EOF. Вы маглі б памылкова лічыць, што ён блакуе альбо: Гэта не так. Вы можаце атрымаць усяго за адзін-б назад, нават калі вы знаходзіцеся далёка EOF. Лена толькі кантроль максімальную суму, якую гатовыя прыняць.
int BufferedReader.read ( char[] m, int offset, int len )
мае аналагічныя Гоча. Вы павінны выкарыстоўваць java.io.DataInputStream.readFully, калі вы хочаце атрымаць усе байты вы прасілі.

Чытаць руціннай іншая праблема. Гэта пасткі і ігнаруе IOException S, а не перадаючы іх на вас. Каб абыйсці як вышэй праблемы, вы можаце выкарыстоўваць свае ўласныя чытаць руціннай так:

Для больш складаных код для працы з праблемай загрузкі com.mindprod.http пакет і спампаваць com.mindprod.filetransfer пакет. Вы таксама можаце паглядзець некаторыя з кода ў HTTP- запісу.

Аплеты не можа выкарыстоўваць лакальны жорсткі дыск

Сама ідэя аплет з'яўляецца абарона карыстальнікаў ад вас пакласці любыя файлы ці ўмяшанне з любым файлаў на сваім цвёрдым дыску, так што вы будзеце мець, каб падмануць, калі вы хочаце, каб ваш аплет, каб мець магчымасць пісаць ці чытаць яго лакальным жорсткім дыску. Вось сем магчымасці:
  1. Дайце карыстачу новы менеджэр бяспекі, які павінен быць усталяваны спецыяльна, што дае дазвол толькі аплет вашага пісаць на дыск. На жаль, гэта не будзе працаваць, калі хто-небудзь робіць тое ж самае. Бяспека менеджэры ўсё яшчэ нагадвае чорную магію. Я яшчэ не бачыў ніякіх дакументаў аб тым, наколькі вы маглі б зрабіць гэта.
  2. Пераўтварэнне аплет для прыкладання. Карыстальнік мае магчымасць спампаваць і ўсталяваць яго, знайсці і ўсталяваць нейкую аўтаномная сістэма Java для сваёй платформы, а затым запусціць яго. Вось так!
  3. Стварыць роднай клас, каб падмануць і зрабіць ўводу/вываду за спіной бяспекі мэнэджэра. Вам трэба будзе напісаць такі родны клас для кожнай іншай платформе, то арганізаваць, каб ён усталяваны асобна раней часу. Ой! Нават у гэтым выпадку вам усё роўна прыйдзецца допуску для запуску роднай клас.
  4. Выкарыстаньне JavaScript або Active-X або іншыя схемы вар'ята, які клапоціцца не рыс для забеспячэння бяспекі.
  5. Ўступіць у шэрагі іншых праграмістаў з іх паходнямі і віламі патрабуюць нейкую хімера - палова аплет паловы дадатку. Гэта будзе дазволены доступ да абмежаваным аб'ёмам дыскавай прасторы, і ня будуць мець доступ да любых файлаў яно не стварае. Яна можа праходзіць ўнутры браўзэра. Гэта будзе мець універсальны характар. Вы маглі б зрабіць аўтаномнай ўвод дадзеных, напрыклад затым загрузіць ці захаваць інфармацыю прыкладання перавагу, кэш дадзеных сервера,...
  6. Выкарыстаньне перавагі Internet Explorer, калі ў вас спіс сайтаў прыкладання, як "давераных сайтаў", то калі вы ўстанавілі зоны бяспекі для "Надзейныя вузлы" на "Custom" і змяніць наладкі, такія, што Java дазволу "Неабмежаваны" і " Запуск прыкладанняў і файлаў "ўключана, вось так!, вы зможаце пісаць/чытаць файлы з лакальнага цвёрдага дыска ўнутры аплета. На жаль, Netscape не мае аналагаў функцыя.
  7. Лобі для агульнага наладжваецца карыстальнікам Security Manager, які дазваляе карыстальнікам ОК розных Naughty паводзін ад канкрэтных аплетаў. Аплет б інтэрфейс для запыту дазволу на спецыяльнае дазвол з мінімальным патрабаванням і ідэальна.

Адноўленая сериализованных аб'ектаў

Працэс серыялізацыі і аднаўленні аб'ектаў спалучана з праблемамі. Што б вы маглі зрабіць для таго, пераходныя поля ў рэканструяваных аб'ектаў правільна ініцыялізаваны?

"Broken" перафарбоўку

Вельмі часта пачаткоўцаў праблемы з'яўляецца адмова перафарбаваць () для перамалёўкі экрана. Перафарбаваць () працуе, мяркуючы аб'ект у чарзе, каб нагадаць сістэмы для планавання фарбы () пазней. Ён ніколі не будзе абыйсці на абслугоўванне чэргі, калі вы не хутка вярнуцца з вашага метаду ініцыялізацыі, або апрацоўкі націску клавішы або кнопкі для прэсы. Выклік Thread.sleep () проста робіць яшчэ горш, так як бягучы паток з'яўляецца той, які будзе пазней зрабіць фарбу ().

Схаваная кампаненты не застанецца незаўважанай

setEnabled (ілжывыя) адключае кампанента сівых яго. setVisible (ілжывыя) (ака схаваць ()) робіць кампанент цалкам знікаюць, з несапраўднымі (), якая пазначае ўсе, якія змяшчаюць кампаненты як маюць патрэбу спакаваць (), так што навакольныя кампаненты будзе тасуются перарасці ў прасторы яна вызваляе. setVisible (ісціна) (ака шоў ()) таксама адзначае бачных ўсіх змяшчаюцца кампанентаў. Гэта азначае, кампанент ў вас ёсць скрытыя будзе невыносна паказаць сябе ў наступны раз вы setVisible (ісціна) агароджваюць акна. Гэта выпраўлена ў JDK 01/01 +.

Я не ведаю ні аднаго метаду, які дазволіць вам схаваць кампанент, што не адмяняе, у выніку чаго яго месца, прызначанае, без ператасоўкі брат кампанентаў.

Dialog.setBackground не працуе

Дыялог фону атрымлівае скіду, калі дыялогавае рыхтуецца да дысплей, так што ваш выклік setBackground (або setForeground) у канструктар не будзе

public void addNotify()
   {
   super.addNotify();

   setBackground( Color.red );
   }
Дадаць паведаміць стварае аднагодкаў аб'екта. Вы перахопу кода ў адразу пасля аднагодкаў атрымлівае створаны.

Акрамя таго, неабходна дакладна кантраляваць фоне кожнага кампанента. Пераняўшы ад Дыялог будзе проста даць шэры.

Яшчэ адно папярэджанне. У JDK 1.0, мадальных асаблівасць дыялогаў не працуе.

Socket To Me

Socket () канструктар не дазваляюць паказаць тайм-аўт. Змаўчанні 1,5 хвіліны, як правіла, даволі празмерным.

Да NiO, не было выбару (), як функцыянальнасць у разеткі (а калі быць больш гнуткай, у InputStreams) і не было таймаўту ў InputStream.read () метад. Гэта робіць немагчымым для праграмы сервера Socket якія маюць колькасць патокаў менш, чым колькасць карыстальнікаў. Аднак, як мне сказалі, што пры выкарыстанні наяўных () метад спрытна вы можаце гэта выдумкі.

У вас ёсць некаторы кантроль над тайм-ауты з ўласцівасці сетак.

Oracle's Technote Кіраўніцтва па сетцы ўласцівасці: у наяўнасці:

Блюз JSP імпарту

Праблема заключаецца ў ўключаць механізм, які выкарыстоўваецца Tomcat 4.0.3 і, магчыма, іншыя сервера JSP прадукцыі. Мова выкарыстоўвае <% @ Page імпарту = "package.package.class"%> абазначэння для імпарту класаў.

Калі вы карыстаецеся для шаблоннага ўключаюць верхнія і ніжнія колонтитулы, то вы можаце атрымаць ClassNotFoundException калі ўключаны JSP, выкарыстоўвае карыстацкі клас.

ASP распрацоўшчыкі выкарыстоўвалі ў зыходны код, знікаюць у препроцессором ASP і інтэрпрэтуецца як адзін вялікі файл. Па гэтай логіцы імпарт заява будзе чакаць з'яўлення ў верхняй частцы "старонка", дзе большасць PPL аб'явы зменных і вызначыць функцыі ў ASP. Аднак у JSP, рэчы, як правіла, падзеленыя і знаходжання падзеленая на шмат маленькіх файлаў. Вы павінны пераканацца, што такім чынам імпарт ідзе ў кожным файле, які яго выкарыстоўвае, а не толькі ў самым пачатку.

Якія ўводзяць у зман паведамленні аб памылках

Кампілятар глядзіць на зыходны код зусім з іншага пункта гледжання, што людзі робяць. Вы паступова даведацца, што ваш кампілятар на самой справе азначае, калі ён кажа, незразумела, напрыклад, "{чакаецца".

Глядзіце табліцу паведамленняў аб памылках, зараз асобны дакумент.

Крэдыты

Як вы ўжо маглі здагадацца, вельмі многія людзі дапамагалі складаць гэты спіс. Я толькі нядаўна пачаў даваць крэдыт. Калі вы хацелі б дадаць у гэты спіс, калі ласка, паведаміце мне.

На жаль, адрасы электроннай пошты ніжэй, не з'яўляюцца інтэрактыўнымі. Далей вы не можаце капіяваць/ўставіць іх у Вашу паштовую праграму. Неабходна ўручную паўторна ўводзіць іх. Адрасы электроннай пошты графічных *. PNG вобразы, створаныя Masker. Я нязручнасці такім чынам, каб перашкаджаць спамераў ад уборкі адрасы электроннай пошты з вэб-сайта з аўтаматычнай індэксацыі сайта.

Аўтары
Тов ці электроннай пошты Тоў ці
Пол ван Keep электроннай пошты Пол ван Keep
Майк Коулишо электроннай пошты Майк Коулишо
П'ер Baillargeon электроннай пошты П'ер Baillargeon
Біл Ўілкінсан электроннай пошты Біл Ўілкінсан
Патрысія Шанахан электроннай пошты Патрысія Шанахан
Іосіф Bowbeer электроннай пошты Іосіф Bowbeer
Чарльз Томас электроннай пошты Чарльз Томас
Джоэл Крыспа электроннай пошты Джоэл Крыспа
Эрык Наглер электроннай пошты Эрык Наглер
Даніэль Leuck электроннай пошты Даніэль Leuck
Уільям Брогден электроннай пошты Уільям Брогден
Іў Bossu электроннай пошты Іў Bossu
Чад Лодер электроннай пошты Чад Лодер
Savas Алпарслан электроннай пошты Savas Алпарслан
Сайман Гібс электроннай пошты Сымон Гібса
Лоўрэнс Vanhelsuwe электроннай пошты Laurence Vanhelsuwe
Норман Патерсон электроннай пошце Норман Патерсон
Джонатан Фін электроннай пошты Джонатан Фін
Popular Links
Published (Last edited): Apr 30 , source: http://www.mindprod.com/jgloss/gotchas.html