Izkušeni razvijalci Java pogosto jemljejo samoumevne funkcije Java, ki jih novince zmede. Na primer, začetnik je lahko zmeden glede Predmet
razred. Ta objava predstavlja tridelno serijo, v kateri predstavljam in odgovarjam na vprašanja o Predmet
in njegove metode.
King Predmet
V: Kaj je Predmet
razred?
A: The Predmet
razred, ki je shranjen v java.lang
paket je končni superrazred vseh razredov Java (razen Predmet
). Poleg tega se nizi razširijo Predmet
. Vendar se vmesniki ne širijo Predmet
, ki je poudarjeno v oddelku 9.6.3.4 Specifikacije jezika Java: ... upoštevajte, da medtem ko vmesnik nima Predmet
kot nadtip ....
Predmet
izjavlja o naslednjih metodah, o katerih bom v celoti razpravljal kasneje v tej objavi in v nadaljevanju te serije:
klon zaščitenega predmeta ()
logično enako (objekt obj)
zaščitena praznina finalize ()
Razred getClass ()
int hashCode ()
obvestilo o ničnosti ()
void notifyAll ()
String toString ()
neveljavno čakanje ()
neveljavno čakanje (dolga časovna omejitev)
neveljavno čakanje (dolga časovna omejitev, int nanos)
Razred Java podeduje te metode in lahko preglasi katero koli metodo, ki ni deklarirana dokončno
. Na primerdokončno
toString ()
je mogoče preglasiti, medtem ko dokončno
počakaj ()
metod ni mogoče preglasiti.
V: Ali lahko izrecno razširim Predmet
razred?
A: Da, izrecno lahko podaljšate Predmet
. Na primer, preverite seznam 1.
Seznam 1. Izrecno se širi Predmet
uvoz java.lang.Object; javni razred Employee razširi Object {private String name; javni zaposleni (ime niza) {this.name = ime; } javni niz getName () {return ime; } public static void main (String [] args) {Employee emp = new Employee ("John Doe"); System.out.println (emp.getName ()); }}
Seznam 1 lahko sestavite (javac zaposleni.java
) in zaženite nastalo Zaposleni.razred
mapa (java zaposleni
), in opazovali boste John Doe
kot izhod.
Ker prevajalnik samodejno uvozi tipe iz java.lang
paket, uvoz java.lang.Object;
izjava ni potrebna. Java vas tudi ne prisili, da izrecno razširjate Predmet
. Če bi se, ne bi mogli podaljšati nobenega drugega razreda kot Predmet
ker Java omejuje razširitev razreda na en razred. Zato bi običajno podaljšali Predmet
implicitno, kot je prikazano v seznamu 2.
Seznam 2. Implicitno razširitev Predmet
javni razred Zaposlen {ime zasebnega niza; javni zaposleni (ime niza) {this.name = ime; } javni niz getName () {return ime; } public static void main (String [] args) {Employee emp = new Employee ("John Doe"); System.out.println (emp.getName ()); }}
Tako kot na seznamu 1, tudi na seznamu 2 Zaposleni
razred se razširi Predmet
in podeduje njegove metode.
Kloniranje predmetov
V: Kaj pomeni klon ()
metoda izpolniti?
A: The klon ()
metoda ustvari in vrne kopijo predmeta, v katerem je ta metoda poklicana.
V: Kako klon ()
metoda dela?
A:Predmet
izvaja klon ()
kot izvorna metoda, kar pomeni, da je njena koda shranjena v izvorni knjižnici. Ko se ta koda izvede, preveri razred (ali nadrazred) predmeta, ki prikliče, da ugotovi, ali izvaja java.lang.Cloneable
vmesnik - Predmet
se ne izvaja Klonirano
. Če ta vmesnik ni izveden, klon ()
meti java.lang.CloneNotSupportedException
, ki je preverjena izjema (z njo je treba ravnati ali ji prenašati niz klica metode tako, da se v glavo metode doda klavzula throws klon ()
je bil poklican). Če je ta vmesnik izveden, klon ()
dodeli nov objekt in kopira vrednosti polj kličočega predmeta v enakovredna polja novega predmeta in vrne sklic na novi objekt.
V: Kako prikličem datoteko klon ()
metoda za kloniranje predmeta?
A: Glede na sklic na objekt, pokličite klon ()
na tej referenci in vrnite vrnjeni predmet iz Predmet
glede na tip predmeta, ki se klonira. Seznam 3 predstavlja primer.
Seznam 3. Kloniranje predmeta
javni razred CloneDemo izvaja Cloneable {int x; public static void main (String [] args) vrže CloneNotSupportedException {CloneDemo cd = new CloneDemo (); cd.x = 5; System.out.printf ("cd.x =% d% n", cd.x); CloneDemo cd2 = (CloneDemo) cd.clone (); System.out.printf ("cd2.x =% d% n", cd2.x); }}
Seznam 3 navaja a CloneDemo
razred, ki izvaja Klonirano
vmesnik. Ta vmesnik mora biti izveden ali priklic Predmet
je klon ()
metoda bo povzročila vržen CloneNotSupportedException
primer.
CloneDemo
razglasi en sam int
-imenovano polje primerka x
in a glavni ()
metoda, ki izvaja ta razred. glavni ()
je razglašen s klavzulo o metanju, ki preide CloneNotSupportedException
navzgor po klicu metode.
glavni ()
prvi primerki CloneDemo
in inicializira nastalo kopijo primerka x
do 5
. Nato izpiše primerke x
vrednost in prikliče klon ()
v tem primeru vrne vrnjeni predmet v CloneDemo
preden shranite sklic. Končno izpiše klonove x
vrednost polja.
Sestavi seznam 3 (javac CloneDemo.java
) in zaženite aplikacijo (java CloneDemo
). Upoštevati morate naslednje rezultate:
cd.x = 5 cd2.x = 5
V: Zakaj bi moral preglasiti klon ()
metoda?
A: Prejšnjemu primeru ni bilo treba preglasiti klon ()
metoda, ker koda, ki prikliče klon ()
se nahaja v razredu, ki se klonira (tj. CloneDemo
razred). Če pa klon ()
klic se nahaja v drugem razredu, boste morali preglasiti klon ()
. V nasprotnem primeru boste prejeli "klon je zaščitil dostop v objektu
"sporočilo, ker klon ()
je razglašena zaščiten
. Seznam 4 predstavlja preoblikovan seznam 3, da dokaže razveljavitev klon ()
.
Seznam 4. Kloniranje predmeta iz drugega razreda
razred Data implementira Cloneable {int x; @Override public Object clone () vrže CloneNotSupportedException {return super.clone (); }} javni razred CloneDemo {public static void main (String [] args) vrže CloneNotSupportedException {Data data = new Data (); data.x = 5; System.out.printf ("data.x =% d% n", data.x); Podatki data2 = (Data) data.clone (); System.out.printf ("data2.x =% d% n", data2.x); }}
Seznam 4 navaja a Podatki
razred, katerega primerke je treba klonirati. Ta razred izvaja Klonirano
vmesnik za preprečevanje CloneNotSupportedException
pred metanjem, ko klon ()
metoda se prikaže, izjavi int
polje na osnovi primerka x
, in preglasi klon ()
metoda. Ta metoda se izvaja super.clone ()
sklicevati se na svoj superrazred (Predmet
v tem primeru) klon ()
metoda. Prevladujoče klon ()
metoda identificira CloneNotSupportedException
v klavzuli o metu.
Seznam 4 navaja tudi a CloneDemo
razred, ki ustvari primerek Podatki
, inicializira svoje polje primerka, prikaže vrednost polja primerka tega primera, klonira Podatki
in izpiše vrednost polja primerka tega primerka.
Sestavi seznam 4 (javac CloneDemo.java
) in zaženite aplikacijo (java CloneDemo
). Upoštevati morate naslednje rezultate:
data.x = 5 data2.x = 5
V: Kaj je plitvo kloniranje?
A:Plitvo kloniranje (poznan tudi kot plitvo kopiranje) je podvajanje polj predmeta brez podvajanja predmetov, na katere se sklicujejo referenčna polja predmeta (če jih ima). Navedbe 3 in 4 kažejo plitvo kloniranje. Vsak od cd
-, cd2
-, podatkov
-, in podatki2
-referencirana polja identificirajo objekt, ki ima svojo kopijo int
-temelji x
polje.
Plitvo kloniranje dobro deluje, če so vsa polja prvotnega tipa in (v mnogih primerih), kadar se sklicujejo katera koli referenčna polja nespremenljiv (nespremenljivi) predmeti. Če pa je kateri koli predmet, na katerega se sklicuje, spremenljiv, lahko prvotni predmet in njegovi kloni (-i) vidijo spremembe, ki jih naredi kateri koli od teh predmetov. Seznam 5 predstavlja predstavitev.
Seznam 5. Prikaz težave s plitvim kloniranjem v kontekstu referenčnega polja
class Zaposleni izvaja Cloneable {private String name; zasebna int starost; naslov zasebnega naslova; Zaposleni (Ime niza, starost, naslov, naslov) {this.name = ime; this.age = starost; this.address = naslov; } @Override public Object clone () vrže CloneNotSupportedException {return super.clone (); } Naslov getAddress () {povratni naslov; } String getName () {return ime; } int getAge () {vrnitev starosti; }} naslov naslova {private String city; Naslov (niz mesta) {this.city = city; } String getCity () {return city; } void setCity (String city) {this.city = city; }} javni razred CloneDemo {public static void main (String [] args) vrže CloneNotSupportedException {Employee e = new Employee ("John Doe", 49, nov naslov ("Denver")); System.out.printf ("% s:% d:% s% n", e.getName (), e.getAge (), e.getAddress (). GetCity ()); Zaposlen e2 = (Zaposlen) e.clone (); System.out.printf ("% s:% d:% s% n", e2.getName (), e2.getAge (), e2.getAddress (). GetCity ()); e.getAddress (). setCity ("Chicago"); System.out.printf ("% s:% d:% s% n", e.getName (), e.getAge (), e.getAddress (). GetCity ()); System.out.printf ("% s:% d:% s% n", e2.getName (), e2.getAge (), e2.getAddress (). GetCity ()); }}
Seznam 5 predstavlja Zaposleni
, Naslov
, in CloneDemo
razredih. Zaposleni
izjavlja ime
, starost
, in naslov
polja; in ga je mogoče klonirati. Naslov
razglasi naslov mesta, katerega primeri so spremenljivi. CloneDemo
poganja aplikacijo.
CloneDemo
je glavni ()
metoda ustvari Zaposleni
objekt in ga klonira. Nato spremeni ime mesta v izvirniku Zaposleni
predmeta naslov
polje. Ker oboje Zaposleni
predmeti se sklicujejo na isto Naslov
objekt, spremenjeno mesto vidijo oba predmeta.
Sestavi seznam 5 (javac CloneDemo.java
) in zaženite to aplikacijo (java CloneDemo
). Upoštevati morate naslednje rezultate:
John Doe: 49: Denver John Doe: 49: Denver John Doe: 49: Chicago John Doe: 49: Chicago
V: Kaj je globoko kloniranje?
A:Globoko kloniranje (poznan tudi kot globoko kopiranje) je podvajanje polj predmeta tako, da se podvojijo vsi referenčni predmeti. Poleg tega se njihovi referenčni predmeti podvajajo - in tako naprej. Na primer, seznam 6 preoblikuje seznam 5, da izkoristi globoko kloniranje. Prav tako prikazuje kovariantne vrste vrnitve in prožnejši način kloniranja.
Seznam 6. Globoko kloniranje naslov
polje
class Zaposleni izvaja Cloneable {private String name; zasebna int starost; naslov zasebnega naslova; Zaposleni (Ime niza, starost, naslov, naslov) {this.name = ime; this.age = starost; this.address = naslov; } @Override public Employee clone () vrže CloneNotSupportedException {Employee e = (Employee) super.clone (); e.address = address.clone (); vrnitev e; } Naslov getAddress () {povratni naslov; } String getName () {return ime; } int getAge () {vrnitev starosti; }} naslov naslova {private String city; Naslov (niz mesta) {this.city = city; } @Override javni naslov clone () {vrni nov naslov (nov niz (mesto)); } String getCity () {return city; } void setCity (String city) {this.city = city; }} javni razred CloneDemo {public static void main (String [] args) vrže CloneNotSupportedException {Employee e = new Employee ("John Doe", 49, nov naslov ("Denver")); System.out.printf ("% s:% d:% s% n", e.getName (), e.getAge (), e.getAddress (). GetCity ()); Zaposlen e2 = (Zaposlen) e.clone (); System.out.printf ("% s:% d:% s% n", e2.getName (), e2.getAge (), e2.getAddress (). GetCity ()); e.getAddress (). setCity ("Chicago"); System.out.printf ("% s:% d:% s% n", e.getName (), e.getAge (), e.getAddress (). GetCity ()); System.out.printf ("% s:% d:% s% n", e2.getName (), e2.getAge (), e2.getAddress (). GetCity ()); }}
Navedba 6 izkorišča podporo Jave za kovarijantne vrste vrnitve za spremembo vrste vrnitve Zaposleni
prevlada klon ()
metoda iz Predmet
do Zaposleni
. Prednost je v zunanji kodi Zaposleni
lahko klonira Zaposleni
predmeta, ne da bi ga bilo treba oddati v Zaposleni
tip.
Zaposleni
je klon ()
metoda najprej prikliče super.clone ()
, ki plitko kopira ime
, starost
, in naslov
polja. Nato se prikliče klon ()
na naslov
polje, da naredite dvojnik sklica Naslov
predmet.
The Naslov
razred preglasi klon ()
metoda in razkrije nekaj razlik od prejšnjih razredov, ki preglasijo to metodo:
Naslov
se ne izvajaKlonirano
. Ni nujno, ker samoPredmet
jeklon ()
metoda zahteva, da razred izvaja ta vmesnik in toklon ()
metoda ni poklicana.- Prevladujoče
klon ()
metoda ne vržeCloneNotSupportedException
. Ta preverjena izjema je vržena samo izPredmet
jeklon ()
metoda, ki se ne imenuje. Zato izjeme ni treba obdelati ali ji poslati mimo klica metode prek klavzule throws. Predmet
jeklon ()
metoda ni poklicana (nisuper.clone ()
klic), ker plitko kopiranje zaNaslov
razred - kopirate lahko samo eno polje.
Za kloniranje Naslov
predmeta, zadostuje ustvariti novega Naslov
in ga inicializirajte v dvojnik predmeta, na katerega se sklicuje datoteka mesto
polje. Novi Naslov
predmet se nato vrne.