Pred uporabo je treba razrede in predmete v Javi inicializirati. Prej ste že izvedeli, da se polja razredov pri nalaganju razredov inicializirajo na privzete vrednosti in da se predmeti inicializirajo s pomočjo konstruktorjev, vendar je za inicializacijo še več. Ta članek predstavlja vse funkcije Java za inicializacijo razredov in predmetov.
prenos Prenesite kodo Prenesite izvorno kodo, na primer programe v tej vadnici. Ustvaril Jeff Friesen za JavaWorld.Kako inicializirati razred Java
Preden preučimo podporo Jave za inicializacijo razredov, ponovimo korake inicializacije razreda Java. Razmislite o seznamu 1.
Seznam 1. Inicializacija polj razreda na privzete vrednosti
razred SomeClass {statični logični b; statični bajt by; statični znak c; statični dvojnik d; statični plovec f; statični int i; statična dolga l; statični kratki s; statični niz st; }
Seznam 1 označuje razred SomeClass
. Ta razred razglasi devet polj vrst logično
, bajt
, char
, dvojno
, plovec
, int
, dolga
, kratek
, in Vrvica
. Kdaj SomeClass
se naložijo biti vsakega polja na nič, kar razlagate takole:
false 0 \ u0000 0,0 0,0 0 0 0 nič
Prejšnja polja razreda so bila implicitno inicializirana na nič. Polja razredov pa lahko tudi izrecno inicializirate tako, da jim neposredno dodelite vrednosti, kot je prikazano v seznamu 2.
Seznam 2. Inicializacija polj razreda na eksplicitne vrednosti
razred SomeClass {statični logični b = true; statični bajt by = 1; statični znak c = 'A'; statično dvojno d = 2,0; statični plovec f = 3.0f; statični int i = 4; statično dolgo l = 5000000000L; statični kratek s = 20000; statični niz st = "abc"; }
Vrednost vsake naloge mora biti združljiva s tipom vrste polja. Vsaka spremenljivka vrednost shrani neposredno, razen st
. Spremenljiv st
shrani sklic na Vrvica
predmet, ki vsebuje abc
.
Referenčna polja razreda
Ko inicializirate polje razreda, je zakonito, da ga inicializirate na vrednost predhodno inicializiranega polja razreda. Na primer, seznam 3 se inicializira y
do x
vrednost. Obe polji sta inicializirani v 2
.
Seznam 3. Sklicevanje na predhodno prijavljeno polje
razred SomeClass {static int x = 2; statični int y = x; javna statična void main (String [] args) {System.out.println (x); System.out.println (y); }}
Vendar obratno ni zakonito: polja razreda ne morete inicializirati na vrednost pozneje razglašenega polja razreda. Izpiše prevajalnik Java nezakonita nadaljnja referenca
ko naleti na ta scenarij. Razmislite o seznamu 4.
Seznam 4. Poskus sklicevanja na naknadno prijavljeno polje
razred SomeClass {static int x = y; statični int y = 2; javna statična void main (String [] args) {System.out.println (x); System.out.println (y); }}
Prevajalnik bo poročal nezakonita nadaljnja referenca
ko naleti statični int x = y;
. To je zato, ker je izvorna koda zbrana od zgoraj navzdol, prevajalnik pa je še ni videl y
. (To sporočilo bi tudi objavilo, če y
ni bil izrecno inicializiran.)
Bloki za inicializacijo razreda
V nekaterih primerih boste morda želeli izvesti zapletene inicializacije na podlagi razreda. To boste storili po nalaganju razreda in preden bodo iz njega ustvarjeni kakršni koli predmeti (ob predpostavki, da razred ni pripomoček). Za to nalogo lahko uporabite blok za inicializacijo razreda.
A blok za inicializacijo razreda je blok stavkov pred statično
ključna beseda, ki je bila uvedena v telo predavanja. Ko se razred naloži, se ti stavki izvršijo. Razmislite o seznamu 5.
Seznam 5. Inicializacija nizov sinusnih in kosinusnih vrednosti
razred Grafika {statični dvojni [] sinusi, kosinusi; statično {sines = novo dvojno [360]; kosinus = nov dvojnik [360]; for (int i = 0; i <sines.length; i ++) {sines [i] = Math.sin (Math.toRadians (i)); kosinusi [i] = Math.cos (Math.toRadians (i)); }}}
Seznam 5 navaja a Grafika
razred, ki izjavlja sinusov
in kosinusov
spremenljivke matrike. Deklarira tudi blok za inicializacijo razreda, ki ustvari nize s 360 elementi, katerih sklici so dodeljeni sinusov
in kosinusov
. Nato uporabi a za
izjavo za inicializiranje teh elementov matrike na ustrezne vrednosti sinusov in kosinusov s klicem Matematika
razredov greh ()
in cos ()
metode. (Matematika
je del Javine knjižnice standardnih razredov. O tem razredu in teh metodah bom razpravljal v prihodnjem članku.)
Trik v uspešnosti
Ker je zmogljivost za grafične aplikacije pomembna in ker je hitreje dostopati do elementa matrike kot klicati metodo, se razvijalci poslužujejo izvedbenih trikov, kot sta ustvarjanje in inicializacija nizov sinusov in kosinusov.
Združevanje inicializerjev polj razreda in blokov inicializacije razreda
V aplikaciji lahko kombinirate več pobudnikov polj razredov in blokov za inicializacijo razredov. Seznam 6 vsebuje primer.
Seznam 6. Izvajanje inicializacije razreda v vrstnem redu od zgoraj navzdol
razred MCFICIB {static int x = 10; statična dvojna temperatura = 98,6; statično {System.out.println ("x =" + x); temp = (temp - 32) * 5,0 / 9,0; // pretvorba v Celzijev sistem.out.println ("temp =" + temp); } statični int y = x + 5; statično {System.out.println ("y =" + y); } javna statična void main (String [] args) {}}
Seznam 6 razglasi in inicializira par pol razredov (x
in y
) in prijavi par statično
inicializatorji. Sestavite ta seznam, kot je prikazano:
javac MCFICIB.java
Nato zaženite nastalo aplikacijo:
java MCFICIB
Upoštevati morate naslednje rezultate:
x = 10 temp = 37,0 y = 15
Ta izhod razkriva, da se inicializacija razreda izvede v vrstnem redu od zgoraj navzdol.
() metode
Pri prevajanju inicializatorjev razredov in blokov za inicializacijo razredov zbiralnik Java shrani zbrano bajtno kodo (v vrstnem redu od zgoraj navzdol) v posebno metodo z imenom ()
. Kotni nosilci preprečujejo a konflikt imen: ne morete prijaviti a ()
v izvorni kodi, ker <
in >
znaki so v kontekstu identifikatorja nedovoljeni.
Po nalaganju razreda JVM pred klicem pokliče to metodo glavni ()
(kdaj glavni ()
je prisoten).
Poglejmo v notranjost MCFICIB.class
. Naslednja delna demontaža razkrije shranjene podatke za x
, temp
, in y
polja:
Polje # 1 00000290 Dostopne zastave ACC_STATIC 00000292 Ime x 00000294 Deskriptor I 00000296 Atributi Število 0 Polje # 2 00000298 Dostopne zastave ACC_STATIC 0000029a Ime temp 0000029c Deskriptor D 0000029e Atributi Število 0 Polje # 3 000002a0 Dostopne oznake 00000 Att I000 Število atributov 000006002 At2 Imenovanje 000006 Att 0
The Deskriptor
vrstica označuje JVM-je deskriptor tipa za polje. Tip je predstavljen z eno črko: jaz
za int
in D
za dvojno
.
Naslednja delna demontaža razkrije zaporedje ukazov bajt kode za ()
metoda. Vsaka vrstica se začne z decimalno številko, ki identificira odmični naslov, ki temelji na nič, naslednjega navodila:
0 bipush 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 novih 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 nova 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 novih 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 return
Zaporedje ukazov od zamika 0 do zamika 2 je enakovredno naslednjemu pobudniku polja razreda:
statični int x = 10;
Zaporedje ukazov od zamika 5 do zamika 8 je enakovredno naslednjemu pobudniku polja razreda:
statična dvojna temperatura = 98,6;
Zaporedje ukazov od zamika 11 do zamika 80 je enakovredno naslednjemu bloku za inicializacijo razreda:
statično {System.out.println ("x =" + x); temp = (temp - 32) * 5,0 / 9,0; // pretvorba v Celzijev sistem.out.println ("temp =" + temp); }
Zaporedje ukazov od zamika 83 do zamika 88 je enakovredno naslednjemu pobudniku polja razreda:
statični int y = x + 5;
Zaporedje ukazov od zamika 91 do zamika 115 je enakovredno naslednjemu bloku za inicializacijo razreda:
statično {System.out.println ("y =" + y); }
Končno, vrnitev
ukaz z odmikom 118 vrne izvedbo iz ()
na tisti del JVM, ki je poklical to metodo.
Ne skrbite, kaj pomeni bajtkoda
Izvleček te vaje je videti, da se vsa koda v pobudnikih polj razreda 6 in blokih za inicializacijo razredov nahaja v ()
in se izvaja v vrstnem redu od zgoraj navzdol.
Kako inicializirati predmete
Ko je razred naložen in inicializiran, boste pogosto želeli ustvariti predmete iz razreda. Kot ste izvedeli v mojem nedavnem uvodu v programiranje z razredi in predmeti, objekt inicializirate s kodo, ki jo postavite v konstruktor razreda. Razmislite o 7. seznamu.
Seznam 7. Uporaba konstruktorja za inicializacijo predmeta
razred City {ime zasebnega niza; int prebivalstvo; Mesto (ime niza, int prebivalstvo) {this.name = ime; this.population = prebivalstvo; } @Override public String toString () {return ime + ":" + populacija; } public static void main (String [] args) {City newYork = novo mesto ("New York", 8491079); System.out.println (newYork); // Izhod: New York: 8491079}}
Seznam 7 navaja a Mesto
razred s ime
in prebivalstva
polja. Ko a Mesto
objekt je ustvarjen, Mesto (ime niza, int prebivalstvo)
konstruktor je poklican, da ta polja inicializira v argumente klicanega konstruktorja. (Preglasil sem tudi Predmet
je javni String toString ()
metoda za priročno vrnitev imena mesta in vrednosti prebivalstva kot niz. System.out.println ()
končno pokliče to metodo, da vrne nizovno predstavitev predmeta, ki jo izpiše.)
Kakšne vrednosti naredijo, preden pokličete konstruktor ime
in prebivalstva
vsebujejo? To lahko ugotovite z vstavljanjem System.out.println (to.ime); System.out.println (this.population);
na začetku konstruktorja. Po sestavi izvorne kode (javac City.java
) in zagon aplikacije (java City
), bi opazili nič
za ime
in 0
za prebivalstva
. The novo
operator pred izvajanjem konstruktorja poništi polja predmeta (primerka) predmeta.
Kot pri poljih razreda lahko tudi izrecno inicializirate polja predmetov. Lahko na primer določite Ime niza = "New York";
ali int prebivalstvo = 8491079;
. Vendar s tem običajno ničesar ne pridobimo, ker bodo ta polja inicializirana v konstruktorju. Edina korist, na katero se lahko spomnim, je dodelitev privzete vrednosti polju predmeta; ta vrednost se uporablja, ko pokličete konstruktor, ki polja ne inicializira:
int numDoors = 4; // privzeta vrednost, dodeljena numDoors Car (String make, String model, int year) {this (znamka, model, leto, numDoors); } Avto (znamka niza, model niza, int leto, int numDoors) {this.make = znamka; this.model = model; this.year = leto; this.numDoors = numDoors; }