<h2>Кіріспе</h2>Бағдарламалау тілі, адамдар сөйлейтін, өмір сүретін және өзгертетін тіл сияқты, тілді қолдануды ыңғайлы ету үшін онда жаңа құбылыстар пайда болады. Ал біз білетіндей, тіл біздің ойымызды ыңғайлы түрде білдіруі керек.
Сонымен, Java SE 5 жүйесінде бокс/бокс ашу механизмі енгізілді. Ал Oracle-дан бөлек оқулық ойды білдірудің осы құралының ерекшеліктеріне арналған: Autoboxing және Unboxing . <h2>Авто-орау боксы</h2>Автоматты буып-түю боксының мысалын қарастырайық. Алдымен, оның қалай жұмыс істейтінін көрейік. Compilejava.net сайтын қолданып , класс құрайық:
Бұл бірдей атышулы «bytecode». Бірақ қазір біз үшін маңыздысы - біз не көреміз. Алдымен, 8080 примитиві әдісті орындау стекіне орналастырылады, содан кейін Integer.valueOf орындалады . Бұл бокстың «сиқыры». Ал сиқырдың ішкі көрінісі келесідей:
Яғни, мәні бойынша, жаңасы кэштен алынады
Көріп отырғаныңыздай, сиқыр жоқ. Барлығы Java ішінде. Ол жай ғана «өздігінен» жұмыс істейді. Біздің ыңғайлылығымыз үшін. <h2>Тырма</h2>
Кез келген құрал, егер дұрыс пайдаланылмаса, өзіне қарсы күшті қаруға айналады. 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);
}
}
Қарапайым code. Біз енгізу параметрін көрсетіп, порт мәнін өзгерте аламыз. Көріп отырғанымыздай, өйткені біз параметрлерден порт мәнін оқимыз , оны арқылы алу арқылы String
аламыз . Сондықтан біз оны қарабайыр тип ретінде емес, нысан түрі ретінде көрсетуге мәжбүрміз . Міне, бір жағынан, бізде an objectінің айнымалысы бар, ал әдепкі мән - қарабайыр. Және ол жұмыс істейді. Бірақ біз сиқырға сенбейміз, солай ма? Олар айтқандай, «қапшық астына» назар аударайық. «ZIP жүктеп алу» түймесін басу арқылы compilejava.net сайтынан бастапқы codeты жүктеп алыңыз. Осыдан кейін жүктелген мұрағатты каталогқа шығарып, оған өтіңіз. Енді мынаны орындаймыз: мұнда App.class - сынып үшін құрастырылған сынып файлы. Біз келесідей мазмұнды көреміз: Integer
Integer.valueOf
Integer
javap -c -p App.class
Integer
немесе алынады (кэш тек бүтін сандар массивінен басқа ештеңе емес) санның мәніне байланысты. Integer
Әрине, Integer
мұндай бақыт бір ғана емес. Қатысты қарабайыр типтердің және олардың орауыштарының толық тізімі бар (OOP әлеміндегі примитивтерді көрсететін сыныптар). Бұл тізім Oracle оқулығының ең төменгі жағында берілген: « Автобокс және қораптан шығару ». Қарапайым элементтерден жасалған массивтерде үшінші тарап кітапханаларын қоспай-ақ «орама» жоқ екенін бірден атап өткен жөн. Анау. -дан біз үшін Arrays.asList
жасамайды . <h2>Қораптан шығару</h2>Боксқа кері процесс қораптан шығару деп аталады. Қаптаманы ашу мысалын қарастырайық: 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
тек примитивтерді қабылдайды. Енді не істеу керек? Қаптама класында бұл жағдай үшін қарабайыр мәнді қайтаратын арнайы әдіс бар. Мысалы, бұл intValueInteger
әдісі . Егер біз byte codeты қарасақ, ол келесідей:
==
. Менің ойымша, бұл түсінікті, бірақ оны қайтадан қарастырайық:
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
}
Бірінші жағдайда мән Integer
мән кэшінен алынады (жоғарыдағы Boxing түсіндірмесін қараңыз), ал екінші жағдайда әр жолы жаңа нысан жасалады. Бірақ бұл жерде брондау керек. Бұл әрекет кэштің жоғарғы шегіне байланысты ( java.lang.Integer.IntegerCache.high ). Сонымен қатар, бұл шектеу басқа параметрлерге байланысты өзгеруі мүмкін. Осы тақырып бойынша талқылауды stackoverflow бойынша оқуға болады: Бүтін кэш қаншалықты үлкен? Әрине, an objectілерді теңдік арқылы салыстыру қажет: System.out.println(notInCache.equals(notInCache2));
Бірдей механизммен байланысты екінші мәселе өнімділік болып табылады. Java тіліндегі кез келген бокс жаңа нысан жасаумен бірдей. Егер нөмір кэш мәндеріне қосылмаса (яғни -128-ден 127-ге дейін), әр жолы жаңа нысан жасалады. Егер кенеттен орау (яғни бокс) циклде орындалса, бұл қажетсіз заттардың үлкен өсуіне және қоқыс жинағыштың жұмысы үшін ресурстарды тұтынуға әкеледі. Сондықтан бұл туралы тым абай болмаңыз. Үшінші, кем емес ауыртпалық бір механизмнен туындайды:
public static void check(Integer value) {
if (value <= 0) {
throw new IllegalStateException("Value is too small");
}
}
Бұл codeта адам қатені айналып өтпеуге тырысты. Бірақ тексеру жоқ null
. Егер бұл кіріске келетін болса null
, онда түсінікті қатенің орнына түсініксіз қатені аламыз NullPointerException
. Салыстыру үшін Java орындауға тырысады value.intValue
және бұзылады, себебі... value
болады null
. <h2>Қорытынды</h2>Қорытынды/қорытындылау механизмі бағдарламашыға аз code жазуға мүмкіндік береді және кейде тіпті қарабайырлардан an objectілерге және кері түрлендіру туралы ойламайды. Бірақ бұл оның қалай жұмыс істейтінін ұмыту керек дегенді білдірмейді. Әйтпесе, сіз бірден пайда болмайтын қателік жібере аласыз. Жүйенің толық бақылауымызда болмайтын бөліктеріне (мысалы, бүтін сан шекарасы) сенбеу керек. Бірақ орауыш сыныптарының барлық артықшылықтары туралы ұмытпаңыз (мысалы 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'));
}
Бәрінен дұрыс қорытынды – сиқыр жоқ, қандай да бір іске асыру бар. Және бәрі әрқашан біз күткендей бола бермейді. Мысалы, қаптама жоқ: System.out.println("The number is " + 8);
Жоғарыдағы мысалды компилятор бір жолға оңтайландырады. Яғни, сіз «сан 8» деп жазған сияқтысыз. Төмендегі мысалда да қаптама болмайды:
public static void main(String[] args) {
System.out.println("The number is " + Math.abs(-2));
}
println
Біз an objectіні кіріс ретінде қабылдағанда және қандай да бір жолмен сызықтарды қосу керек болғанда, бұл қалай болуы мүмкін . Сызықтар... иә, сондықтан мұндай қаптама жоқ. Статикалық әдістер бар Integer
, бірақ олардың кейбіреулері package
. Яғни, біз оларды пайдалана алмаймыз, бірақ Java-ның өзінде оларды белсенді түрде қолдануға болады. Бұл жерде дәл солай. GetChars әдісі шақырылады, ол саннан таңбалар массивін жасайды. Тағы да, сиқыр жоқ, тек Java). Сондықтан кез келген түсініксіз жағдайда сіз жай ғана іске асыруды қарауыңыз керек және кем дегенде бір нәрсе орнына түседі. #Вячеслав
GO TO FULL VERSION