JavaRush /Java Blog /Random-TL /Pagtatalaga at Pagsisimula sa Java

Pagtatalaga at Pagsisimula sa Java

Nai-publish sa grupo

Panimula

Ang pangunahing layunin ng mga programa sa computer ay pagproseso ng data. Upang maproseso ang data kailangan mong iimbak ito kahit papaano. Iminumungkahi kong maunawaan kung paano iniimbak ang data.
Pagtatalaga at Pagsisimula sa Java - 1

Mga variable

Ang mga variable ay mga lalagyan na nag-iimbak ng anumang data. Tingnan natin ang opisyal na Tutorial mula sa Oracle: Declaring Member Variables . Ayon sa Tutorial na ito, mayroong ilang mga uri ng mga variable:
  • Mga Patlang : mga variable na ipinahayag sa klase;
  • Mga lokal na variable : mga variable sa isang paraan o bloke ng code;
  • Mga Parameter : mga variable sa deklarasyon ng pamamaraan (sa lagda).
Ang lahat ng mga variable ay dapat magkaroon ng isang variable na uri at isang variable na pangalan.
  • Isinasaad ng uri ng variable kung anong data ang kinakatawan ng variable (iyon ay, kung anong data ang maiimbak nito). Tulad ng alam natin, ang uri ng isang variable ay maaaring primitive (primitives ) o object , hindi primitive (Non-primitive). Sa mga variable ng object, ang kanilang uri ay inilalarawan ng isang partikular na klase.
  • Ang variable na pangalan ay dapat na lowercase, sa camel case. Maaari kang magbasa nang higit pa tungkol sa pagpapangalan sa " Variables:Naming ".
Gayundin, kung ang isang variable sa antas ng klase, i.e. ay isang field ng klase, maaaring tukuyin ang isang access modifier para dito. Tingnan ang Pagkontrol sa Pag-access sa Mga Miyembro ng isang Klase para sa higit pang mga detalye .

Pahayag ng Variable

Kaya, naaalala natin kung ano ang isang variable. Upang magsimulang magtrabaho sa isang variable, kailangan mong ideklara ito. Una, tingnan natin ang isang lokal na variable. Sa halip na isang IDE, para sa kaginhawahan, gagamitin namin ang online na solusyon mula sa tutorialspoint: Online IDE . Patakbuhin natin ang simpleng program na ito sa kanilang online na IDE:
public class HelloWorld{
    public static void main(String []args){
        int number;
        System.out.println(number);
    }
}
Kaya, tulad ng nakikita mo, nagdeklara kami ng isang lokal na variable na may pangalan numberat uri int. Pinindot namin ang pindutang "Ipatupad" at makuha ang error:
HelloWorld.java:5: error: variable number might not have been initialized
        System.out.println(number);
Anong nangyari? Nagdeklara kami ng variable, ngunit hindi sinimulan ang halaga nito. Kapansin-pansin na ang error na ito ay hindi nangyari sa oras ng pagpapatupad (ibig sabihin, hindi sa Runtime), ngunit sa oras ng pagsasama-sama. Sinuri ng smart compiler kung ang lokal na variable ay masisimulan bago ito i-access o hindi. Samakatuwid, ang mga sumusunod na pahayag ay sumusunod mula dito:
  • Ang mga lokal na variable ay dapat lamang ma-access pagkatapos na masimulan ang mga ito;
  • Ang mga lokal na variable ay walang mga default na halaga;
  • Ang mga halaga ng mga lokal na variable ay sinusuri sa oras ng pag-compile.
Kaya, sinabi sa amin na ang variable ay dapat masimulan. Ang pagsisimula ng isang variable ay ang pagtatalaga ng isang halaga sa isang variable. Alamin natin kung ano ito at bakit.

Pagsisimula ng isang lokal na variable

Ang pagsisimula ng mga variable ay isa sa mga nakakalito na paksa sa Java, dahil... ay napakalapit na nauugnay sa pagtatrabaho sa memorya, ang pagpapatupad ng JVM, ang pagtutukoy ng JVM at iba pang mga nakakatakot at nakakalito na bagay. Ngunit maaari mong subukang malaman ito kahit sa ilang lawak. Mula sa simple hanggang sa kumplikado. Upang simulan ang variable, gagamitin namin ang assignment operator at baguhin ang linya sa aming nakaraang code:
int number = 2;
Sa pagpipiliang ito, walang mga error at ang halaga ay ipapakita sa screen. Ano ang mangyayari sa kasong ito? Subukan nating mangatwiran. Kung gusto naming magtalaga ng value sa isang variable, gusto naming mag-store ng value ang variable na iyon. Ito ay lumiliko na ang halaga ay dapat na naka-imbak sa isang lugar, ngunit saan? Sa disk? Ngunit ito ay napakabagal at maaaring magpataw ng mga paghihigpit sa amin. Lumalabas na ang tanging lugar kung saan maaari tayong mabilis at mahusay na mag-imbak ng data "dito at ngayon" ay memorya. Nangangahulugan ito na kailangan nating maglaan ng ilang espasyo sa memorya. Ito ay totoo. Kapag ang isang variable ay nasimulan, ang espasyo ay ilalaan para dito sa memorya na inilaan sa proseso ng java kung saan ang aming programa ay isasagawa. Ang memorya na inilalaan sa isang proseso ng java ay nahahati sa ilang mga lugar o zone. Alin sa kanila ang maglalaan ng espasyo ay depende sa kung anong uri ang variable ay idineklara. Ang memorya ay nahahati sa mga sumusunod na seksyon: Heap, Stack at Non-Heap . Magsimula tayo sa stack memory. Ang stack ay isinalin bilang isang stack (halimbawa, isang stack ng mga libro). Ito ay isang LIFO (Last In, First Out) na istraktura ng data. Ibig sabihin, parang salansan ng mga libro. Kapag nagdagdag kami ng mga aklat dito, inilalagay namin ang mga ito sa itaas, at kapag inalis namin ang mga ito, kukunin namin ang nangunguna (i.e. ang pinakakamakailang idinagdag). Kaya, inilunsad namin ang aming programa. Tulad ng alam natin, ang isang Java program ay pinaandar ng isang JVM, iyon ay, isang Java virtual machine. Dapat malaman ng JVM kung saan dapat magsimula ang pagpapatupad ng programa. Upang gawin ito, ipinapahayag namin ang isang pangunahing pamamaraan, na tinatawag na "entry point". Para sa pagpapatupad sa JVM, isang pangunahing thread (Thread) ay nilikha. Kapag ang isang thread ay nilikha, ito ay inilalaan ng sarili nitong stack sa memorya. Ang stack na ito ay binubuo ng mga frame. Kapag ang bawat bagong paraan ay naisakatuparan sa isang thread, isang bagong frame ang ilalaan para dito at idaragdag sa tuktok ng stack (tulad ng isang bagong libro sa isang stack ng mga libro). Maglalaman ang frame na ito ng mga sanggunian sa mga bagay at primitive na uri. Oo, oo, ang aming int ay maiimbak sa stack, dahil... Ang int ay isang primitive na uri. Bago maglaan ng frame, dapat na maunawaan ng JVM kung ano ang ise-save doon. Dahil dito makakatanggap kami ng error na "maaaring hindi nasimulan ang variable", dahil kung hindi ito nasimulan, hindi maihahanda ng JVM ang stack para sa amin. Samakatuwid, kapag nag-compile ng isang programa, ang isang matalinong compiler ay tutulong sa atin na maiwasan ang magkamali at masira ang lahat. (!) Para sa kalinawan, inirerekomenda ko ang isang super-duper na artikulo: " Java Stack and Heap: Java Memory Allocation Tutorial ". Nagli-link ito sa isang parehong cool na video:
Matapos makumpleto ang pagpapatupad ng isang pamamaraan, ang mga frame na inilalaan para sa mga pamamaraang ito ay tatanggalin mula sa stack ng thread, at kasama ng mga ito ang memorya na inilaan para sa frame na ito kasama ang lahat ng data ay iki-clear.

Sinisimulan ang mga Lokal na Variable ng Bagay

Baguhin nating muli ang ating code sa medyo mas nakakalito:
public class HelloWorld{

    private int number = 2;

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

}
Ano ang mangyayari dito? Pag-usapan natin ito muli. Alam ng JVM kung saan dapat isagawa ang programa, i.e. nakikita niya ang pangunahing pamamaraan. Lumilikha ito ng isang thread at naglalaan ng memorya para dito (pagkatapos ng lahat, ang isang thread ay kailangang mag-imbak ng data na kailangan para sa pagpapatupad sa isang lugar). Sa thread na ito, isang frame ang inilalaan para sa pangunahing pamamaraan. Susunod na lumikha kami ng isang bagay na HelloWorld. Ang bagay na ito ay hindi na nilikha sa stack, ngunit sa heap. Dahil ang object ay hindi isang primitive type, ngunit isang object type. At ang stack ay mag-iimbak lamang ng reference sa object sa heap (kailangan natin kahit papaano ma-access ang object na ito). Susunod, sa stack ng pangunahing pamamaraan, ang mga frame ay ilalaan para sa pagpapatupad ng paraan ng println. Pagkatapos isagawa ang pangunahing pamamaraan, masisira ang lahat ng mga frame. Kung ang frame ay nawasak, ang lahat ng data ay masisira. Ang object object ay hindi agad masisira. Una, ang reference dito ay masisira at sa gayon ay wala nang magre-refer sa object object at ang access sa object na ito sa memorya ay hindi na posible. Ang isang matalinong JVM ay may sariling mekanismo para dito - isang kolektor ng basura (pangongolekta ng basura o GC para sa maikling salita). Pagkatapos ay inaalis nito mula sa mga bagay sa memorya na walang ibang tinutukoy. Ang prosesong ito ay muling inilarawan sa link na ibinigay sa itaas. Mayroong kahit isang video na may paliwanag.

Pagsisimula ng mga patlang

Ang pagsisimula ng mga field na tinukoy sa isang klase ay nangyayari sa isang espesyal na paraan depende sa kung ang field ay static o hindi. Kung ang isang field ay may keyword na static, ang field na ito ay tumutukoy sa klase mismo, at kung ang salitang static ay hindi tinukoy, ang field na ito ay tumutukoy sa isang instance ng klase. Tingnan natin ito sa isang halimbawa:
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);
    }
}
Sa halimbawang ito, ang mga field ay sinisimulan sa iba't ibang oras. Ang field ng numero ay pasisimulan pagkatapos malikha ang bagay ng klase ng HelloWorld. Ngunit ang count field ay masisimulan kapag ang klase ay na-load ng Java virtual machine. Ang pag-load ng klase ay isang hiwalay na paksa, kaya hindi namin ito paghaluin dito. Ito ay nagkakahalaga lamang na malaman na ang mga static na variable ay sinisimulan kapag ang klase ay naging kilala sa runtime. May iba pang mas mahalaga dito, at napansin mo na ito. Hindi namin tinukoy ang halaga kahit saan, ngunit gumagana ito. At walang pag aalinlangan. Ang mga variable na mga field, kung wala silang tinukoy na halaga, sinisimulan ang mga ito gamit ang isang default na halaga. Para sa mga numerong halaga ito ay 0 o 0.0 para sa mga numero ng floating point. Para sa boolean ito ay hindi totoo. At para sa lahat ng mga variable ng uri ng object ang halaga ay magiging null (pag-uusapan natin ito mamaya). Mukhang, bakit ganito? Ngunit dahil ang mga bagay ay nilikha sa Heap (sa heap). Ang trabaho sa lugar na ito ay isinasagawa sa Runtime. At maaari nating simulan ang mga variable na ito sa runtime, hindi tulad ng stack, ang memorya kung saan dapat ihanda bago isagawa. Ito ay kung paano gumagana ang memorya sa Java. Ngunit may isa pang tampok dito. Ang maliit na piraso ay nakakaantig sa iba't ibang sulok ng memorya. Tulad ng naaalala natin, ang isang frame ay inilalaan sa Stack memory para sa pangunahing pamamaraan. Ang frame na ito ay nag-iimbak ng reference sa isang bagay sa Heap memory. Ngunit saan nakaimbak ang bilang? Tulad ng natatandaan natin, ang variable na ito ay agad na sinisimulan, bago ang object ay nilikha sa heap. Ito ay talagang nakakalito na tanong. Bago ang Java 8, mayroong isang lugar ng memorya na tinatawag na PERMGEN. Simula sa Java 8, ang lugar na ito ay nagbago at tinatawag na METASPACE. Mahalaga, ang mga static na variable ay bahagi ng kahulugan ng klase, i.e. metadata nito. Samakatuwid, lohikal na ito ay nakaimbak sa metadata repository, METASPACE. Ang MetaSpace ay kabilang sa parehong Non-Heap memory area at bahagi nito. Mahalaga rin na isaalang-alang na ang pagkakasunud-sunod kung saan ang mga variable ay ipinahayag ay isinasaalang-alang. Halimbawa, mayroong error sa code na ito:
public class HelloWorld{

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

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

}

Ano ang null

Tulad ng nakasaad sa itaas, ang mga variable ng mga uri ng object, kung sila ay mga field ng isang klase, ay sinisimulan sa mga default na halaga at ang default na halaga ay null. Ngunit ano ang null sa Java? Ang unang bagay na dapat tandaan ay ang mga primitive na uri ay hindi maaaring null. At lahat dahil ang null ay isang espesyal na sanggunian na hindi tumutukoy kahit saan, sa anumang bagay. Samakatuwid, isang object variable lamang ang maaaring maging null. Ang pangalawang bagay na mahalagang maunawaan ay ang null ay isang sanggunian. Ang tinutukoy ko ay mayroon ding kanilang timbang. Sa paksang ito, maaari mong basahin ang tanong sa stackoverflow: " Nangangailangan ba ang null variable ng espasyo sa memorya ".

Mga bloke ng pagsisimula

Kapag isinasaalang-alang ang pagsisimula ng mga variable, magiging kasalanan na hindi isaalang-alang ang mga bloke ng pagsisimula. Mukhang ganito:
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();
    }

}
Ang pagkakasunud-sunod ng output ay magiging: static block, block, Constructor. Tulad ng nakikita natin, ang mga bloke ng pagsisimula ay isinasagawa bago ang tagabuo. At kung minsan ito ay maaaring maging isang maginhawang paraan ng pagsisimula.

Konklusyon

Umaasa ako na ang maikling pangkalahatang-ideya na ito ay nakapagbigay ng ilang insight sa kung paano ito gumagana at bakit. #Viacheslav
Mga komento
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION