<h2> Giriş </h2> Programmirleme dili, adamlaryň gürleýän dili, ýaşaýşy we üýtgemegi ýaly, dil ulanmagy has amatly etmek üçin onda täze hadysalar peýda bolýar. Bilşimiz ýaly dil pikirlerimizi aňsatlyk bilen beýan etmeli.
Şeýlelik bilen, Java SE 5-de boks / gutujy mehanizm girizildi. Oracle-dan aýratyn bir sapak, pikirleri beýan etmegiň bu serişdeleriniň aýratynlyklaryna bagyşlanýar: Awtobokslamak we açmak . <h2> Awto-gaplaýyş boksy </h2> Geliň, awto-gaplaýan boksyň mysalyna seredeliň. Ilki bilen, onuň nähili işleýändigini göreliň. Compilejava.net sahypasyny ulanalyň we synp döredeliň:
Bu şol bir meşhur “bytekod”. Emma indi biziň üçin möhüm zat görýänlerimizdir. Ilki bilen 8080 başlangyç usuly ýerine ýetiriş stakasyna ýerleşdirilýär, soň bolsa Integer.valueOf ýerine ýetirilýär . Bu boksyň “jadysy”. Jadygöýüň içinde şeýle görünýär:
.Agny, aslynda, keşiň bahasyna baglylykda täze keş alynar
Görşüňiz ýaly jady ýok. Hemme zat Java-da. Diňe “özi” işleýär. Amatlylygymyz üçin. <h2> Rake </h2>
Любой инструмент при неправильном использовании становится грозным оружием против самого себя. И механизм автоупаковка и распаковка boxing/unboxing в Java не исключение. Первое, очевидное, сравнение через
public class App {
public static void main(String[] args) {
Integer portNumber = 8080;
if (args.length != 0) {
portNumber = Integer.valueOf(args[0]);
}
System.out.println("Port number is: " + portNumber);
}
}
Pleönekeý kod. Giriş parametrini kesgitläp, port bahasyny üýtgedip bileris. Görşümiz ýaly, sebäbi portuň bahasyny parametrlerden okaýarys String
, Integer
ony geçip alýarys Integer.valueOf
. Şonuň üçin biz ony başlangyç görnüş hökmünde däl-de, obýekt görnüşi hökmünde kesgitlemäge mejbur bolýarys Integer
. Ine, bir tarapdan, obýekt üýtgeýjimiz bar, deslapky baha başlangyç. Bu işleýär. Emma jadylara ynanamzok, şeýlemi? Geliň, olaryň aýdyşy ýaly “kapotyň aşagyna” seredeliň. Çeşme koduny “ZIP ýüklemek” düwmesine basyp, compilejava.net-den göçürip alyň. Ondan soň göçürilen arhiwi kataloga çykaryň we oňa geçiň. Indi edeliň: javap -c -p App.class
bu ýerde App.class synpyňyz üçin düzülen synp faýlydyr. Munuň ýaly mazmuny göreris:
Integer
ýa-da keşden alynar (keş keşi diňe Integers massiwinden başga zat däl). Integer
Elbetde, Integer
diňe bir beýle bagtly däldi. Baglanyşykly başlangyç görnüşleriň we olaryň örtükleriniň doly sanawy bar (OOP dünýäsinde ilkinjileri görkezýän synplar). Bu sanaw Oracle-dan Tutorial-yň iň aşaky böleginde berilýär: “ Awtobokslamak we gutulmak ”. Ilkinjilerden ýasalan massiwleriň üçünji tarap kitaphanalaryny birikdirmezden “örtüginiň” ýokdugyny derrew bellemelidiris. Bular. bizden Arrays.asList
ýasamaz . _ <h2> Blokdan çykarmak </h2> Boksyň tersine prosesi gutusyz gutusyna diýilýär. Açylýan mysala seredeliň: int[]
List
Integer
public class App {
public static void main(String[] args) {
if (args.length == 0) {
System.out.println("Please, enter params");
return;
}
int value = Math.abs(Integer.valueOf(args[0]));
System.out.println("Absolute value is: " + value);
}
}
Math.abs
diňe başlangyçlary kabul edýär. Näme etmeli? Örtük synpynda bu başlangyç üçin ýönekeý bir usul bar. Mysal üçin, bu intValueInteger
usulydyr . Baýtkoda seretsek, bu şeýle:
==
. Думаю, это понятно, но разберём ещё раз:
public static void main(String[] args) {
Integer inCacheValue = 127;
Integer inCacheValue2 = 127;
Integer notInCache = 128; // new Integer(129)
Integer notInCache2 = 128; // new Integer(129)
System.out.println(inCacheValue == inCacheValue2); //true
System.out.println(notInCache == notInCache2); //false
}
В первом случае, meaning берётся из кэша Integer
значений (см. объяснение Boxing выше), а во втором случае будет создаваться каждый раз новый an object. Но тут стоит оговориться. Это поведение зависит от верхней границы кэша (java.lang.Integer.IntegerCache.high). Кроме того, эта граница может измениться и из-за других настроек. На эту тему можно ознакомиться с обсуждением на stackoverflow: How large is the Integer cache? Естественно, an objectы нужно сравнивать через equals: System.out.println(notInCache.equals(notInCache2));
Вторая проблема, связанная с этим же механизмом – производительность. Любая упаковка в Java равносильна созданию нового an object. Если число не входит в значения из кэша (т.е. в -128 до 127), то будет каждый раз создаваться новый an object. Если вдруг упаковка (т.е. boxing) будет производиться в цикле, это вызовет огромный прирост ненужных an objectов и потребление ресурсов на работу сборщика мусора. Поэтому, не стоит слишком безрассудно относится к этому. Третьи не менее больные грабли вытекают из того же механизма:
public static void check(Integer value) {
if (value <= 0) {
throw new IllegalStateException("Value is too small");
}
}
В этом codeе человек явно пытался не пройти мимо ошибки. Но тут нет проверки на null
. Если на вход придёт null
, то instead of понятной ошибки мы получим невнятный NullPointerException
. Потому что для сравнения Java попробует выполнить value.intValue
и свалится, т.к. value
будет null
. <h2>Вывод</h2>Механизм boxing/unboxing позволяет программисту писать меньше codeа и даже порой не думать о преобразовании из примитивов в an objectы и обратно. Но это не значит, что нужно забывать, How это работает. Иначе можно допустить ошибку, которая может всплыть не сразу. Не стоит полагаться на части системы, которые не fully под нашим контролем (How например граница integer). Но и не стоит забывать про все преимущества классов-обёрток (вроде Integer
). Часто эти классы-обёртки имеют набор дополнительных статических методов, которые сделают вашу жизнь лучше, а code – выразительнее. Вот пример в догонку:
public static void main(String[] args) {
int first = 1;
int second = 5;
System.out.println(Integer.max(first, second));
System.out.println(Character.toLowerCase('S'));
}
Так же правильный вывод из всего - нет магии, есть Howая-то реализация. И не везде будет всегда то, что мы ожидаем. Например тут нет упаковки: System.out.println("The number is " + 8);
Пример выше компилятором будет соптимизирован в одну строку. То есть словно вы написали «The number is 8». И в примере ниже тоже не будет упаковки:
public static void main(String[] args) {
System.out.println("The number is " + Math.abs(-2));
}
Как же так, когда у нас println
принимает на вход an object и нужно How-то соединить строки. Строки… да, именно поэтому нет упаковки, How таковой. У Integer
есть статические методы, но некоторые из них уровня package
. То есть мы их не можем использовать, а вот в самой Java они могут активно использоваться. Вот тут How раз такой случай. Будет вызван метод getChars, который из числа делает массив символов. Опять же, ниHowой магии, только Java ). Так что в любой непонятной ситуации стоит просто посмотреть реализацию и хоть что-то да встанет на свои места. #Viacheslav
GO TO FULL VERSION