Programiranje

Inicializacija razredov in predmetov v Javi

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 xvrednost. 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 Predmetje 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; }

Inicializacija predmeta zrcali inicializacijo razreda

$config[zx-auto] not found$config[zx-overlay] not found