Prieš naudojant, „Java“ klasės ir objektai turi būti inicializuoti. Anksčiau sužinojote, kad klasių laukai yra inicializuojami pagal numatytąsias reikšmes, kai įkeliamos klasės, ir kad objektai inicijuojami per konstruktorius, tačiau inicializavimo yra daugiau. Šiame straipsnyje pateikiamos visos „Java“ funkcijos, skirtos inicijuoti klases ir objektus.
atsisiųsti Gauti kodą Atsisiųskite šaltinį, pvz., programas, šioje pamokoje. Sukūrė Jeffas Friesenas, skirtas „JavaWorld“.Kaip inicijuoti „Java“ klasę
Prieš tyrinėdami „Java“ palaikymą klasės inicializavimui, pakartokime „Java“ klasės inicializavimo veiksmus. Apsvarstykite 1 sąrašą.
Sąrašas 1. Inicijuojami klasės laukai pagal numatytąsias reikšmes
klasė SomeClass {statinis loginis b; statinis baitas; statinis char c; statinis dvigubas d; statinė plūdė f; statinis int i; statinis ilgas l; statiniai trumpieji s; statinis Styginių g. }
1 sąrašas deklaruoja klasę SomeClass
. Ši klasė deklaruoja devynis tipų laukus loginis
, baitas
, char
, dvigubai
, plūdė
, tarpt
, ilgas
, trumpas
ir Stygos
. Kada SomeClass
yra įkeltas, kiekvieno lauko bitai nustatomi į nulį, kurį interpretuojate taip:
klaidingas 0 \ u0000 0.0 0.0 0 0 0 null
Ankstesni klasės laukai buvo netiesiogiai inicijuoti iki nulio. Tačiau taip pat galite aiškiai inicijuoti klasės laukus, tiesiogiai priskirdami jiems vertes, kaip parodyta 2 sąraše.
Sąrašas 2. Inicijuojami klasės laukai, kad būtų aiškios reikšmės
klasė SomeClass {statinis loginis b = teisingas; statinis baitas = 1; statinė char c = 'A'; statinis dvigubas d = 2,0; statinė plūdė f = 3,0f; statinis int i = 4; statinis ilgis l = 5000000000L; statinis trumpasis s = 20000; statinė eilutė st = "abc"; }
Kiekvienos užduoties vertė turi būti suderinama su klasės lauko tipu. Kiekvienas kintamasis įrašo vertę tiesiogiai, išskyrus šv
. Kintamas šv
saugo nuorodą į a Stygos
objektas, kuriame yra abc
.
Nurodomi klasės laukai
Inicijuojant klasės lauką, teisėta jį inicijuoti pagal anksčiau inicijuoto klasės lauko vertę. Pavyzdžiui, inicijuojamas 3 sąrašas y
į x
vertė. Abu laukai inicijuojami 2
.
Sąrašas 3. Nuoroda į anksčiau deklaruotą lauką
klasė SomeClass {static int x = 2; statinis int y = x; public static void main (String [] args) {System.out.println (x); System.out.println (y); }}
Tačiau atvirkščiai nėra teisėta: negalima inicijuoti klasės lauko pagal vėliau deklaruoto klasės lauko vertę. „Java“ kompiliatoriaus išvestys neteisėta išankstinė nuoroda
kai susiduria su šiuo scenarijumi. Apsvarstykite 4 sąrašą.
Sąrašas 4. Bandymas nurodyti vėliau deklaruotą lauką
klasė SomeClass {static int x = y; statinis int y = 2; public static void main (String [] args) {System.out.println (x); System.out.println (y); }}
Kompiliatorius praneš neteisėta išankstinė nuoroda
kai susiduria statinis int x = y;
. Taip yra todėl, kad šaltinio kodas yra sudarytas iš viršaus į apačią, o kompiliatorius dar nematė y
. (Tai taip pat išleistų šį pranešimą, jei y
nebuvo aiškiai inicijuota.)
Klasės inicializavimo blokai
Kai kuriais atvejais galbūt norėsite atlikti sudėtingus klasių inicializavimus. Tai atliksite po to, kai klasė bus įkelta ir prieš kuriant bet kokius objektus iš tos klasės (darant prielaidą, kad klasė nėra naudingumo klasė). Šiai užduočiai galite naudoti klasės inicialų bloką.
A klasės inicializavimo blokas yra teiginių blokas, prieš kurį rašoma statinis
raktinis žodis, įvestas į klasės kūną. Kai klasė įkeliama, šie sakiniai vykdomi. Apsvarstykite 5 sąrašą.
Sąrašas 5. Inicijuojami sinuso ir kosinuso reikšmių masyvai
klasės grafika {statiniai dvigubi [] sinusai, kosinusai; statinis {sinusai = naujas dvigubas [360]; kosinusas = naujas dvigubas [360]; už (int i = 0; i <sinusų.ilgis; i ++) {sinusai [i] = Math.sin (Math.toRadians (i)); kosinusai [i] = Math.cos (Math.toRadians (i)); }}}
5 sąrašas skelbia a Grafika
klasė, kuri deklaruoja sinusai
ir kosinusai
masyvo kintamieji. Ji taip pat deklaruoja klasės inicializavimo bloką, kuris sukuria 360 elementų masyvus, kuriems priskiriamos nuorodos sinusai
ir kosinusai
. Tada jis naudoja a dėl
sakinys inicializuoti šiuos masyvo elementus iki atitinkamų sinusų ir kosinusų reikšmių, iškviečiant Matematika
klasės nuodėmė ()
ir cos ()
metodai. (Matematika
yra „Java“ standartinės klasės bibliotekos dalis. Aptarsiu šią klasę ir šiuos metodus būsimame straipsnyje.)
Veiklos triukas
Kadangi grafikos programoms našumas yra svarbus ir kad greičiau pasiekti masyvo elementą nei iškviesti metodą, kūrėjai griebiasi našumo gudrybių, tokių kaip sinusų ir kosinusų masyvų kūrimas ir inicijavimas.
Derinant klasės lauko inicialus ir klasės inicijavimo blokus
Programoje galite sujungti kelis klasės lauko iniciatorius ir klasės inicializavimo blokus. 6 sąrašas pateikia pavyzdį.
Sąrašas 6. Vykdant klasės inicijavimą iš viršaus į apačią
klasė MCFICIB {static int x = 10; statinė dviguba temperatūra = 98,6; statinis {System.out.println ("x =" + x); temp = (temp - 32) * 5,0 / 9,0; // konvertuoti į Celsijaus sistemą.out.println ("temp =" + temp); } statinis int y = x + 5; statinis {System.out.println ("y =" + y); } public static void main (String [] args) {}}
6 sąrašas skelbia ir inicializuoja porą klasės laukų (x
ir y
), ir deklaruoja porą statinis
iniciatoriai. Sudarykite šį sąrašą, kaip parodyta:
javac MCFICIB.java
Tada paleiskite gautą programą:
java MCFICIB
Turėtumėte stebėti šį rezultatą:
x = 10 temp = 37,0 y = 15
Ši išvestis atskleidžia, kad klasės inicijavimas atliekamas „iš viršaus į apačią“ tvarka.
() metodai
Kompiliuodamas klasės inicialus ir klasės inicializavimo blokus, „Java“ kompiliatorius sukompiliuotą baitkodą (tvarka iš viršaus į apačią) saugo specialiu metodu, pavadintu ()
. Kampiniai laikikliai neleidžia a vardų konfliktas: negalite deklaruoti a ()
metodas šaltinio kode, nes <
ir >
simboliai yra neteisėti identifikatoriaus kontekste.
Įkėlus klasę, JVM prieš skambindamas iškviečia šį metodą pagrindinis ()
(kada pagrindinis ()
yra).
Pažvelkime į vidų MCFICIB.klasė
. Šis dalinis išmontavimas atskleidžia saugomą x
, temp
ir y
laukai:
Lauko # 1 00000290 Prieigos Vėliavos ACC_STATIC 00.000.292 Vardas x 00000294 deskriptorius Aš 00000296 atributai Count 0 laukas # 2 00000298 Prieigos Vėliavos ACC_STATIC 0000029a Vardas temperatūra 0000029c deskriptorius D 0000029e atributai Count 0 laukas # 3 000002a0 prieigos Vėliavos ACC_STATIC 000002a2 Vardas Y 000002a4 deskriptorius Aš 000002a6 atributai Count 0
Deskriptorius
eilutė identifikuoja JVM tipo deskriptorius laukui. Tipą žymi viena raidė: Aš
dėl tarpt
ir D
dėl dvigubai
.
Šis dalinis išardymas atskleidžia baito kodo instrukcijų seką ()
metodas. Kiekviena eilutė prasideda dešimtainiu skaičiumi, kuris identifikuoja tolesnio nurodymo nulinės vertės poslinkio adresą:
0 dvipusis 10 2 putstatic MCFICIB / x I 5 ldc2_w # 98.6 8 putstatic MCFICIB / temp D 11 getstatic java / lang / System / out Ljava / io / PrintStream; 14 naujų java / lang / StringBuilder 17 dup 18 invokespecial java / lang / StringBuilder / () V 21 ldc "x =" 23 invokevirtual java / lang / StringBuilder / append (Ljava / lang / String;) Ljava / lang / StringBuilder; 26 getstatic MCFICIB / x I 29 invokevirtual java / lang / StringBuilder / append (I) Ljava / lang / StringBuilder; 32 invokevirtual java / lang / StringBuilder / toString () Ljava / lang / String; 35 invokevirtual java / io / PrintStream / println (Ljava / lang / String;) V 38 getstatic MCFICIB / temp D 41 ldc2_w # 32 44 dsub 45 ldc2_w # 5 48 dmul 49 ldc2_w # 9 52 ddiv 53 putstatic MCFICIB / temp D 56 getstatic java / lang / System / out Ljava / io / PrintStream; 59 naujas java / lang / StringBuilder 62 dup 63 invokespecial java / lang / StringBuilder / () V 66 ldc "temp =" 68 invokevirtual java / lang / StringBuilder / append (Ljava / lang / String;) Ljava / lang / StringBuilder; 71 getstatic MCFICIB / temp D 74 invokevirtual java / lang / StringBuilder / append (D) Ljava / lang / StringBuilder; 77 invokevirtual java / lang / StringBuilder / toString () Ljava / lang / String; 80 invokevirtual java / io / PrintStream / println (Ljava / lang / String;) V 83 getstatic MCFICIB / x I 86 iconst_5 87 iadd 88 putstatic MCFICIB / y I 91 getstatic java / lang / System / out Ljava / io / PrintStream; 94 naujas java / lang / StringBuilder 97 dup 98 invokespecial java / lang / StringBuilder / () V 101 ldc "y =" 103 invokevirtual java / lang / StringBuilder / append (Ljava / lang / String;) Ljava / lang / StringBuilder; 106 getstatic MCFICIB / y I 109 invokevirtual java / lang / StringBuilder / append (I) Ljava / lang / StringBuilder; 112 invokevirtual java / lang / StringBuilder / toString () Ljava / lang / String; 115 invokevirtual java / io / PrintStream / println (Ljava / lang / String;) V 118 grįžti
Komandų seka nuo 0 poslinkio iki 2 poslinkio prilygsta tokiam klasės lauko iniciatoriui:
statinis int x = 10;
Instrukcijų seka nuo 5 poslinkio iki 8 poslinkio prilygsta tokiam klasės lauko iniciatoriui:
statinė dviguba temperatūra = 98,6;
Komandų seka nuo 11 poslinkio iki 80 poslinkio prilygsta šiam klasės inicializavimo blokui:
statinis {System.out.println ("x =" + x); temp = (temp - 32) * 5,0 / 9,0; // konvertuoti į Celsijaus sistemą.out.println ("temp =" + temp); }
Komandų seka nuo 83 poslinkio iki 88 poslinkio yra ekvivalenti tokiam klasės lauko iniciatoriui:
statinis int y = x + 5;
Nurodymų seka nuo 91 poslinkio iki 115 poslinkio yra lygi tokiam klasės inicializavimo blokui:
statinis {System.out.println ("y =" + y); }
Galiausiai grįžti
instrukcija 118 poslinkyje grąžina vykdymą iš ()
į tą JVM dalį, kuri vadino šį metodą.
Nesijaudinkite, ką reiškia baitų kodas
Iš šio pratimo reikia įsitikinti, kad visi 6 sąrašo klasės lauko iniciatorių ir klasės inicializavimo blokų kodai yra ()
metodas, ir vykdomas „iš viršaus į apačią“ tvarka.
Kaip inicijuoti objektus
Po to, kai klasė buvo įkelta ir inicializuota, dažnai norėsite sukurti klasės objektus. Kaip jūs sužinojote mano naujausioje programavimo su klasėmis ir objektais įžangoje, jūs inicijuojate objektą naudodami kodą, kurį įdedate į klasės konstruktorių. Apsvarstykite 7 sąrašą.
Sąrašas 7. Konstruktoriaus naudojimas objektui inicializuoti
klasė Miestas {privatus eilutės pavadinimas; int populiacija; Miestas (eilutės pavadinimas, gyventojų skaičius) {this.name = vardas; tai.populiacija = populiacija; } @Paisyti viešosios eilutės toString () {return name + ":" + populiacija; } public static void main (String [] args) {Miestas newYork = naujas miestas ("Niujorkas", 8491079); System.out.println (newYork); // Išvestis: Niujorkas: 8491079}}
7 sąrašas skelbia a Miestas
klasė su vardas
ir gyventojų
laukai. Kada Miestas
sukurtas objektas, Miestas (eilutės pavadinimas, gyventojų skaičius)
konstruktorius kviečiamas inicializuoti šiuos laukus pagal iškviesto konstruktoriaus argumentus. (Aš taip pat nepaisiau Objektas
's viešoji styginių eilutė ()
metodas patogiai grąžinti miesto pavadinimą ir gyventojų vertę kaip eilutę. System.out.println ()
galų gale iškviečia šį metodą, kad grąžintų objekto eilutės atvaizdą, kurį jis pateikia.)
Prieš skambinant konstruktoriui, kokias reikšmes daro vardas
ir gyventojų
turėti? Tai galite sužinoti įterpdami System.out.println (this.name); System.out.println (tai populiacija);
prasidėjus konstruktoriui. Sudarius šaltinio kodą (javac City.java
) ir paleisti programą (java miestas
), jūs pastebėtumėte niekinis
dėl vardas
ir 0
dėl gyventojų
. naujas
operatorius nuleidžia objekto objekto (egzemplioriaus) laukus prieš vykdydamas konstruktorių.
Kaip ir klasės laukuose, galite aiškiai inicijuoti objekto laukus. Pavyzdžiui, galite nurodyti Stygos pavadinimas = "Niujorkas";
arba int populiacija = 8491079;
. Tačiau tai padarius paprastai nėra ko gauti, nes šie laukai bus inicializuoti konstruktoriuje. Vienintelis pranašumas, kurį galiu sugalvoti, yra numatytosios reikšmės priskyrimas objekto laukui; ši reikšmė naudojama iškviečiant konstruktorių, kuris neinicijuoja lauko:
int numDoors = 4; // numatytoji reikšmė priskirta numDoors Car (String make, String model, int metai) {this (markė, modelis, metai, numDoors); } Automobilis (Styginių markė, Styginių modelis, int metai, int numDoors) {this.make = markė; tai.modelis = modelis; tai.metai = metai; this.numDoors = numDoors; }