JavaRush /Java blogi /Random-UZ /Java-da tayinlash va ishga tushirish
Viacheslav
Daraja

Java-da tayinlash va ishga tushirish

Guruhda nashr etilgan

Kirish

Kompyuter dasturlarining asosiy maqsadi ma'lumotlarni qayta ishlashdir. Ma'lumotlarni qayta ishlash uchun siz uni qandaydir tarzda saqlashingiz kerak. Men ma'lumotlar qanday saqlanishini tushunishni taklif qilaman.
Java-da tayinlash va ishga tushirish - 1

O'zgaruvchilar

O'zgaruvchilar har qanday ma'lumotlarni saqlaydigan konteynerlardir. Keling, Oracle-dan rasmiy qo'llanmani ko'rib chiqaylik: a'zo o'zgaruvchilarni e'lon qilish . Ushbu qo'llanmaga ko'ra, o'zgaruvchilarning bir nechta turlari mavjud:
  • Maydonlar : sinfda e'lon qilingan o'zgaruvchilar;
  • Lokal o'zgaruvchilar : metod yoki kod blokidagi o'zgaruvchilar;
  • Parametrlar : usul deklaratsiyasidagi o'zgaruvchilar (imzoda).
Barcha o'zgaruvchilar o'zgaruvchi turiga va o'zgaruvchi nomiga ega bo'lishi kerak.
  • O'zgaruvchining turi o'zgaruvchi qanday ma'lumotlarni ifodalashini (ya'ni qanday ma'lumotlarni saqlashi mumkinligini) ko'rsatadi. Ma'lumki, o'zgaruvchining turi ibtidoiy (primitives primitives ) yoki ob'ekt , primitiv bo'lmagan (Non-primitive) bo'lishi mumkin. Ob'ekt o'zgaruvchilari bilan ularning turi ma'lum bir sinf tomonidan tavsiflanadi.
  • O'zgaruvchi nomi tuya harfida bosh harf bilan yozilishi kerak. Nomlash haqida ko'proq ma'lumotni " Variables:Naming " bo'limida o'qishingiz mumkin .
Bundan tashqari, agar sinf darajasi o'zgaruvchisi bo'lsa, ya'ni. sinf maydoni bo'lib, unga kirish modifikatori ko'rsatilishi mumkin. Qo'shimcha ma'lumot olish uchun Sinf a'zolariga kirishni nazorat qilish qarang .

O'zgaruvchan deklaratsiya

Shunday qilib, biz o'zgaruvchining nima ekanligini eslaymiz. O'zgaruvchi bilan ishlashni boshlash uchun siz uni e'lon qilishingiz kerak. Birinchidan, mahalliy o'zgaruvchini ko'rib chiqaylik. IDE o'rniga, qulaylik uchun biz tutorialspoint dan onlayn yechimdan foydalanamiz: Onlayn IDE . Keling, ushbu oddiy dasturni ularning onlayn IDE-da ishga tushiraylik:
public class HelloWorld{
    public static void main(String []args){
        int number;
        System.out.println(number);
    }
}
Shunday qilib, siz ko'rib turganingizdek, biz name numberva type bilan mahalliy o'zgaruvchini e'lon qildik int. Biz "Bajarish" tugmasini bosamiz va xatoni olamiz:
HelloWorld.java:5: error: variable number might not have been initialized
        System.out.println(number);
Nima bo'ldi? Biz o'zgaruvchini e'lon qildik, lekin uning qiymatini ishga tushirmadik. Shuni ta'kidlash kerakki, bu xato bajarilish vaqtida emas (ya'ni, Runtime'da emas), balki kompilyatsiya vaqtida sodir bo'lgan. Aqlli kompilyator mahalliy o'zgaruvchiga kirishdan oldin ishga tushiriladimi yoki yo'qligini tekshirdi. Shunday qilib, quyidagi bayonotlar bundan kelib chiqadi:
  • Mahalliy o'zgaruvchilarga faqat ishga tushirilgandan so'ng kirish kerak;
  • Mahalliy o'zgaruvchilar standart qiymatlarga ega emas;
  • Mahalliy o'zgaruvchilarning qiymatlari kompilyatsiya vaqtida tekshiriladi.
Shunday qilib, bizga o'zgaruvchini ishga tushirish kerakligi aytiladi. O'zgaruvchini ishga tushirish o'zgaruvchiga qiymat berishdir. Keling, nima ekanligini va nima uchun ekanligini aniqlaylik.

Mahalliy o'zgaruvchini ishga tushirish

O'zgaruvchilarni ishga tushirish Java-dagi eng qiyin mavzulardan biridir, chunki... xotira bilan ishlash, JVMni amalga oshirish, JVM spetsifikatsiyasi va boshqa bir xil darajada qo'rqinchli va qiyin narsalar bilan chambarchas bog'liq. Lekin siz buni hech bo'lmaganda ma'lum darajada tushunishga harakat qilishingiz mumkin. Keling, oddiydan murakkabga o'tamiz. O'zgaruvchini ishga tushirish uchun biz tayinlash operatoridan foydalanamiz va oldingi kodimizdagi qatorni o'zgartiramiz:
int number = 2;
Ushbu parametrda hech qanday xato bo'lmaydi va qiymat ekranda ko'rsatiladi. Bu holatda nima sodir bo'ladi? Keling, fikr yuritishga harakat qilaylik. Agar biz o'zgaruvchiga qiymat berishni istasak, u holda biz ushbu o'zgaruvchi qiymatni saqlashini xohlaymiz. Ma'lum bo'lishicha, qiymat bir joyda saqlanishi kerak, lekin qayerda? Diskdami? Ammo bu juda sekin va bizga cheklovlar qo'yishi mumkin. Ma'lum bo'lishicha, biz ma'lumotlarni "bu erda va hozir" tez va samarali saqlashimiz mumkin bo'lgan yagona joy bu xotira. Bu xotirada biroz joy ajratishimiz kerakligini anglatadi. Ha shunaqa. O'zgaruvchi ishga tushirilganda, dasturimiz bajariladigan java jarayoniga ajratilgan xotirada unga joy ajratiladi. Java jarayoniga ajratilgan xotira bir necha soha yoki zonalarga bo'linadi. Ulardan qaysi biri bo'sh joy ajratishi o'zgaruvchining qaysi turi e'lon qilinganiga bog'liq. Xotira quyidagi bo'limlarga bo'linadi: Uyum, Stack va Non-Heap . Keling, stek xotirasidan boshlaylik. Stack stek deb tarjima qilinadi (masalan, kitoblar to'plami). Bu LIFO (Last In, First Out) ma'lumotlar tuzilmasi. Ya'ni, kitoblar to'plami kabi. Unga kitoblarni qo'shganda, biz ularni ustiga qo'yamiz va ularni olib qo'yganimizda, biz eng yuqori qismini (ya'ni, eng yaqinda qo'shilgan) olamiz. Shunday qilib, biz dasturimizni ishga tushiramiz. Ma'lumki, Java dasturi JVM, ya'ni Java virtual mashinasi tomonidan bajariladi. JVM dasturning bajarilishi qayerdan boshlanishi kerakligini bilishi kerak. Buning uchun biz "kirish nuqtasi" deb ataladigan asosiy usulni e'lon qilamiz. JVM da bajarish uchun asosiy ip (Thread) yaratiladi. Tarmoq yaratilganda, u xotirada o'z stekini ajratadi. Bu stek ramkalardan iborat. Har bir yangi usul ipda bajarilganda, unga yangi ramka ajratiladi va stekning yuqori qismiga qo'shiladi (kitoblar to'plamidagi yangi kitob kabi). Ushbu ramka ob'ektlar va ibtidoiy turlarga havolalarni o'z ichiga oladi. Ha, ha, bizning int stekda saqlanadi, chunki... int ibtidoiy tipdir. Kadrni ajratishdan oldin JVM u erda nimani saqlash kerakligini tushunishi kerak. Aynan shuning uchun biz "o'zgaruvchi ishga tushirilmagan bo'lishi mumkin" xatosini olamiz, chunki u ishga tushirilmagan bo'lsa, JVM biz uchun stek tayyorlay olmaydi. Shuning uchun, dasturni kompilyatsiya qilishda, aqlli kompilyator xatolarga yo'l qo'ymaslik va hamma narsani buzishga yordam beradi. (!) Aniqlik uchun men o'ta noaniq maqolani tavsiya qilaman: " Java Stack and Heap: Java Memory Allocation Tutorial ". U bir xil darajada ajoyib videoga havola qiladi:
Usulning bajarilishi tugallangandan so'ng, ushbu usullar uchun ajratilgan freymlar ip stekidan o'chiriladi va ular bilan birga barcha ma'lumotlar bilan ushbu ramka uchun ajratilgan xotira tozalanadi.

Mahalliy ob'ekt o'zgaruvchilarni ishga tushirish

Keling, kodimizni yana biroz murakkabroq qilib o'zgartiraylik:
public class HelloWorld{

    private int number = 2;

    public static void main(String []args){
        HelloWorld object = new HelloWorld();
        System.out.println(object.number);
    }

}
Bu erda nima bo'ladi? Keling, bu haqda yana gaplashaylik. JVM dasturni qayerdan bajarishi kerakligini biladi, ya'ni. u asosiy usulni ko'radi. U ish zarrachasini yaratadi, unga xotira ajratadi (oxir-oqibat, ip bir joyda bajarilishi uchun zarur bo'lgan ma'lumotlarni saqlashi kerak). Ushbu ipda asosiy usul uchun ramka ajratilgan. Keyin HelloWorld ob'ektini yaratamiz. Ushbu ob'ekt endi stekda emas, balki to'pda yaratiladi. Chunki ob'ekt ibtidoiy tip emas, balki ob'ekt tipidir. Va stek faqat ob'ektga havolani uyada saqlaydi (biz qandaydir tarzda bu ob'ektga kirishimiz kerak). Keyinchalik, asosiy usul stekida println usulini bajarish uchun ramkalar ajratiladi. Asosiy usulni bajargandan so'ng, barcha ramkalar yo'q qilinadi. Agar ramka buzilgan bo'lsa, barcha ma'lumotlar yo'q qilinadi. Ob'ekt ob'ekti darhol yo'q qilinmaydi. Birinchidan, unga havola yo'q qilinadi va shuning uchun endi hech kim ob'ekt ob'ektiga murojaat qilmaydi va xotiradagi ushbu ob'ektga kirish endi mumkin bo'lmaydi. Buning uchun aqlli JVM o'z mexanizmiga ega - axlat yig'uvchi (axlat yig'uvchi yoki qisqacha GC). Keyin u hech kim havola qilmaydigan ob'ektlarni xotiradan olib tashlaydi. Bu jarayon yana yuqorida keltirilgan havolada tasvirlangan. Hatto tushuntirishli video ham bor.

Maydonlarni ishga tushirish

Sinfda ko'rsatilgan maydonlarni ishga tushirish maydonning statik yoki yo'qligiga qarab maxsus tarzda sodir bo'ladi. Agar maydonda static kalit so'zi bo'lsa, u holda bu maydon sinfning o'ziga tegishli bo'lsa va agar static so'zi ko'rsatilmagan bo'lsa, u holda bu maydon sinfning namunasiga ishora qiladi. Keling, buni misol bilan ko'rib chiqaylik:
public class HelloWorld{
    private int number;
    private static int count;

    public static void main(String []args){
        HelloWorld object = new HelloWorld();
        System.out.println(object.number);
    }
}
Ushbu misolda maydonlar turli vaqtlarda ishga tushirilgan. Raqam maydoni HelloWorld sinf ob'ekti yaratilgandan so'ng ishga tushiriladi. Biroq, sinf Java virtual mashinasi tomonidan yuklanganda hisoblash maydoni ishga tushiriladi. Sinfni yuklash alohida mavzu, shuning uchun biz uni bu erda aralashtirmaymiz. Statik o'zgaruvchilar sinf ish vaqtida ma'lum bo'lganda ishga tushirilishini bilish kerak. Bu erda yana bir narsa muhimroq va siz buni allaqachon payqagansiz. Biz hech bir joyda qiymatni ko'rsatmadik, lekin u ishlaydi. Va albatta. Maydonlar bo'lgan o'zgaruvchilar, agar ularda belgilangan qiymat bo'lmasa, ular standart qiymat bilan ishga tushiriladi. Raqamli qiymatlar uchun bu suzuvchi nuqtali raqamlar uchun 0 yoki 0,0 ni tashkil qiladi. Boolean uchun bu noto'g'ri. Va barcha ob'ekt tipidagi o'zgaruvchilar uchun qiymat null bo'ladi (bu haqda keyinroq gaplashamiz). Ko'rinib turibdiki, nega bu shunday? Lekin ob'ektlar Uyda (uyma ichida) yaratilganligi sababli. Bu soha bilan ishlash Runtime dasturida amalga oshiriladi. Va biz ushbu o'zgaruvchilarni ish vaqtida ishga tushirishimiz mumkin, stekdan farqli o'laroq, xotirasi bajarilishidan oldin tayyorlanishi kerak. Java-da xotira shunday ishlaydi. Ammo bu erda yana bir xususiyat bor. Ushbu kichik qism xotiraning turli burchaklariga tegadi. Esda tutganimizdek, asosiy usul uchun Stack xotirasida ramka ajratilgan. Ushbu ramka ob'ektga havolani yig'ish xotirasida saqlaydi. Ammo hisob qaerda saqlanadi? Esda tutganimizdek, bu o'zgaruvchi ob'ekt uyada yaratilishidan oldin darhol ishga tushiriladi. Bu haqiqatan ham qiyin savol. Java 8 dan oldin PERMGEN deb nomlangan xotira maydoni mavjud edi. Java 8 dan boshlab, bu soha o'zgardi va METASPACE deb nomlandi. Asosan, statik o'zgaruvchilar sinf ta'rifining bir qismidir, ya'ni. uning metama'lumotlari. Shuning uchun u METASPACE metama'lumotlar omborida saqlanishi mantiqan to'g'ri. MetaSpace bir xil Non-Heap xotira maydoniga tegishli va uning bir qismidir. O'zgaruvchilarni e'lon qilish tartibi hisobga olinishini ham hisobga olish kerak. Masalan, ushbu kodda xatolik bor:
public class HelloWorld{

    private static int b = a;
    private static int a = 1;

    public static void main(String []args){
        System.out.println(b);
    }

}

Null nima

Yuqorida aytib o'tilganidek, ob'ekt turlarining o'zgaruvchilari, agar ular sinfning maydonlari bo'lsa, standart qiymatlarga ishga tushiriladi va bu standart qiymat null bo'ladi. Lekin Java'da null nima? Esda tutish kerak bo'lgan birinchi narsa, ibtidoiy tiplar null bo'lishi mumkin emas. Va barchasi, chunki null - bu hech qanday joyga, hech qanday ob'ektga tegishli bo'lmagan maxsus havola. Shuning uchun faqat ob'ekt o'zgaruvchisi null bo'lishi mumkin. Tushunish kerak bo'lgan ikkinchi narsa - null - bu havola. Men ularning vazniga ham murojaat qilaman. Ushbu mavzu bo'yicha siz stackoverflow bo'yicha savolni o'qishingiz mumkin: " Nul o'zgaruvchi xotirada bo'sh joy talab qiladimi ?".

Initsializatsiya bloklari

O'zgaruvchilarni ishga tushirishni ko'rib chiqayotganda, ishga tushirish bloklarini hisobga olmaslik gunoh bo'ladi. Bu shunday ko'rinadi:
public class HelloWorld{

    static {
        System.out.println("static block");
    }

    {
        System.out.println("block");
    }

    public HelloWorld () {
        System.out.println("Constructor");
    }

    public static void main(String []args){
        HelloWorld obj = new HelloWorld();
    }

}
Chiqish tartibi quyidagicha bo'ladi: statik blok, blok, Konstruktor. Ko'rib turganimizdek, ishga tushirish bloklari konstruktordan oldin bajariladi. Va ba'zida bu ishga tushirishning qulay vositasi bo'lishi mumkin.

Xulosa

Umid qilamanki, bu qisqacha sharh uning qanday ishlashi va nima uchun ekanligini tushunishga yordam berdi. #Viacheslav
Izohlar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION