Pieredzējuši Java izstrādātāji bieži uzskata par pašsaprotamām Java funkcijām, kuras jaunpienācējiem šķiet mulsinošas. Piemēram, iesācējs varētu būt neizpratnē par Objekts
klasē. Šis ieraksts uzsāk trīs daļu sēriju, kurā es iepazīstinu un atbildu uz jautājumiem Objekts
un tās metodes.
King Object
J: Kas ir Objekts
klasē?
A: The Objekts
klase, kas tiek glabāta java.lang
pakete ir visu Java klašu galvenā klase (izņemot Objekts
). Arī masīvi paplašinās Objekts
. Tomēr saskarnes nepaplašinās Objekts
, kas norādīts Java valodas specifikācijas 9.6.3.4. sadaļā: ... uzskatiet, ka, lai gan saskarnei nav Objekts
kā supertips ....
Objekts
paziņo par šādām metodēm, kuras es pilnībā apspriedīšu vēlāk šajā ierakstā un pārējā šajā sērijā:
aizsargāts objekta klons ()
būla skaitlis ir vienāds (Object obj)
aizsargāta anulēšana pabeigt ()
Klase getClass ()
int hashCode ()
anulēt paziņojumu ()
anulēt paziņojumu Visi ()
String toString ()
tukša gaidīšana ()
tukša gaidīšana (ilgs noildze)
tukša gaidīšana (ilgs noildze, int nanos)
Java klase pārmanto šīs metodes un var ignorēt jebkuru metodi, kas nav deklarēta galīgais
. Piemēram,galīgais
toString ()
metodi var ignorēt, turpretī galīgais
pagaidiet ()
metodes nevar ignorēt.
J: Vai es varu skaidri pagarināt Objekts
klasē?
A: Jā, jūs varat skaidri pagarināt Objekts
. Piemēram, skatiet 1. sarakstu.
Saraksts 1. skaidri paplašina Objekts
importēt java.lang.Object; publiskā klase Darbinieks paplašina objektu {privātais virknes nosaukums; publiskais darbinieks (virknes nosaukums) {this.name = vārds; } public String getName () {atgriešanās nosaukums; } public static void main (String [] args) {Employee emp = new Employee ("John Doe"); System.out.println (emp.getName ()); }}
Jūs varat sastādīt 1. sarakstu (javac Employee.java
) un palaist iegūto Darbinieks.klase
fails (java Darbinieks
), un jūs ievērosiet Džons Doe
kā izvadi.
Tā kā kompilators automātiski importē tipus no java.lang
iepakojums importēt java.lang.Object;
paziņojums nav vajadzīgs. Arī Java nepiespiež jūs skaidri paplašināt Objekts
. Ja tas tā būtu, jūs nevarētu pagarināt citas klases, izņemot Objekts
jo Java ierobežo klases paplašināšanu līdz vienai klasei. Tādēļ jūs parasti pagarināt Objekts
netieši, kā parādīts 2. sarakstā.
Uzskaitījums 2. Netieši paplašinās Objekts
public class Darbinieks {private String name; publiskais darbinieks (virknes nosaukums) {this.name = vārds; } public String getName () {atgriešanās nosaukums; } public static void main (String [] args) {Employee emp = new Employee ("John Doe"); System.out.println (emp.getName ()); }}
Tāpat kā 1. sarakstā, 2. sarakstā Darbinieks
klase pagarinās Objekts
un pārmanto tās metodes.
Objektu klonēšana
J: Ko dara klons ()
metodi paveikt?
A: The klons ()
metode izveido un atgriež objekta, uz kuru tiek saukta šī metode, kopiju.
J: Kā notiek klons ()
metode darbojas?
A:Objekts
īsteno klons ()
kā vietējo metodi, kas nozīmē, ka tā kods tiek glabāts dzimtā bibliotēkā. Kad šis kods tiek izpildīts, tas pārbauda izsaucošā objekta klasi (vai virsklasi), lai redzētu, vai tas ievieš java.lang. Klonējams
interfeiss - Objekts
neievieš Klonējams
. Ja šī saskarne nav ieviesta, klons ()
metieni java.lang.CloneNotSupportedException
, kas ir pārbaudīts izņēmums (tas ir jāapstrādā vai jāpārvieto pa metodi-izsaukuma kaudzīti, pievienojot metru klauzulu tās metodes galvenei, kurā klons ()
tika izsaukts). Ja šī saskarne ir ieviesta, klons ()
piešķir jaunu objektu un kopē izsaucošā objekta lauka vērtības jaunā objekta ekvivalentajos laukos un atgriež atsauci uz jauno objektu.
J: Kā es varu izsaukt klons ()
metode objekta klonēšanai?
A: Ņemot vērā objekta atsauci, izsauciet klons ()
uz šīs atsauces un atdodiet atgriezto objektu no Objekts
klonējamā objekta tipam. 3. saraksts ir piemērs.
Saraksts 3. Objekta klonēšana
publiskā klase CloneDemo ievieš Cloneable {int x; public static void main (String [] args) met 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); }}
3. saraksts deklarē a CloneDemo
klase, kas īsteno Klonējams
interfeiss. Šī saskarne ir jāievieš vai jāizsauc Objekts
's klons ()
metodes rezultātā tiks izmests CloneNotSupportedException
instancē.
CloneDemo
paziņo viens int
bāzes instances lauks nosaukts x
un a galvenais ()
metode, kas vingrina šo klasi. galvenais ()
tiek deklarēts ar metienu klauzulu, kas iztur CloneNotSupportedException
uz augšu metodi-zvanu kaudze.
galvenais ()
vispirms acumirklī CloneDemo
un inicializē iegūto instances kopiju x
uz 5
. Pēc tam tā izved instances x
vērtību un izsauc klons ()
šajā gadījumā, nododot atpakaļ objektu CloneDemo
pirms tās atsauces saglabāšanas. Visbeidzot, tas izvada klona x
lauka vērtība.
Sastādīt 3. sarakstu (javac CloneDemo.java
) un palaidiet lietojumprogrammu (java CloneDemo
). Jums jāievēro šāda izeja:
cd.x = 5 cd2.x = 5
J: Kāpēc man vajadzētu ignorēt klons ()
metodi?
A: Iepriekšējam piemēram nevajadzēja ignorēt klons ()
metodi, jo kods, kas izsauc klons ()
atrodas klonējamajā klasē (t.i., CloneDemo
klase). Tomēr, ja klons ()
izsaukums atrodas citā klasē, jums būs jāatsakās klons ()
. Pretējā gadījumā jūs saņemsitklons ir aizsargājis piekļuvi objektam
"ziņojums, jo klons ()
tiek deklarēts aizsargāts
. 4. saraksts parāda pārstrādātu 3. sarakstu, lai parādītu svarīgāko klons ()
.
Saraksts 4. Objekta klonēšana no citas klases
klase Datu rīki Cloneable {int x; @Orride public Object clone () izmet CloneNotSupportedException {return super.clone (); }} public class CloneDemo {public static void main (String [] args) met CloneNotSupportedException {Data data = new Data (); dati.x = 5; System.out.printf ("dati.x =% d% n", dati.x); Datu dati2 = (Dati) dati.klons (); System.out.printf ("dati2.x =% d% n", dati2.x); }}
4. saraksts deklarē a Dati
klase, kuras gadījumus paredzēts klonēt. Šī klase īsteno Klonējams
interfeiss, lai novērstu CloneNotSupportedException
no izmetšanas, kad klons ()
metodi sauc, paziņo int
bāzes instances lauks x
un ignorē klons ()
metodi. Šī metode tiek izpildīta super.klons ()
izmantot tās superklases (Objekts
šajā piemērā) klons ()
metodi. Galvenais klons ()
metode identificē CloneNotSupportedException
tās metienu klauzulā.
4. saraksts arī deklarē a CloneDemo
klase, kas instantizē Dati
, inicializē tā instances lauku, izvada šīs instances instances lauka vērtību, klonē Dati
un izved šīs instances instances lauka vērtību.
Sastādīt 4. sarakstu (javac CloneDemo.java
) un palaidiet lietojumprogrammu (java CloneDemo
). Jums jāievēro šāda izeja:
dati.x = 5 dati2.x = 5
J: Kas ir sekla klonēšana?
A:Sekla klonēšana (zināms arī kā sekla kopēšana) ir objekta lauku dublēšanās, nedublējot nevienu objektu, uz kuru atsaucas objekta atsauces lauki (ja tam ir tādi). 3. un 4. saraksts parāda seklu klonēšanu. Katrs no cd
-, cd2
-, dati
-, un dati2
-referencētie lauki identificē objektu, kuram ir sava int
-pamatots x
laukā.
Seklā klonēšana darbojas labi, ja visi lauki ir primitīva tipa un (daudzos gadījumos), ja uz visiem atsauces laukiem ir atsauce nemainīgs (nemaināmi) objekti. Tomēr, ja kāds atsauces objekts ir maināms, sākotnējā objektā un tā klonā (-os) var redzēt izmaiņas, kas veiktas vienā no šiem objektiem. 5. saraksts piedāvā demonstrāciju.
Saraksts 5. Seklās klonēšanas problēmas parādīšana atsauces lauka kontekstā
klase Darbinieks ievieš Cloneable {private String name; privāts int vecums; privātā adreses adrese; Darbinieks (virknes nosaukums, vecums, adreses adrese) {this.name = vārds; tas.vecums = vecums; this.adress = adrese; } @Orride public Object clone () izmet CloneNotSupportedException {return super.clone (); } Adrese getAddress () {atgriešanās adrese; } String getName () {atgriešanās nosaukums; } int getAge () {atgriešanās vecums; }} klases adrese {private String city; Adrese (virknes pilsēta) {this.city = city; } Virkne getCity () {atgriešanās pilsēta; } void setCity (virknes pilsēta) {this.city = pilsēta; }} public class CloneDemo {public static void main (String [] args) izmet CloneNotSupportedException {Employee e = new Employee ("John Doe", 49, new Address ("Denver")); System.out.printf ("% s:% d:% s% n", e.getName (), e.getAge (), e.getAddress (). GetCity ()); Darbinieks e2 = (Darbinieks) e.klons (); System.out.printf ("% s:% d:% s% n", e2.getName (), e2.getAge (), e2.getAddress (). GetCity ()); e.getAddress (). setCity ("Čikāga"); 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 ()); }}
Uzskaitot 5 dāvanas Darbinieks
, Adrese
, un CloneDemo
klases. Darbinieks
paziņo nosaukums
, vecums
, un adrese
lauki; un ir klonējams. Adrese
paziņo, ka adrese sastāv no pilsētas, un tās gadījumi ir maināmi. CloneDemo
vada lietojumprogrammu.
CloneDemo
's galvenais ()
metode rada Darbinieks
objektu un klonē šo objektu. Tad tas maina pilsētas nosaukumu oriģinālā Darbinieks
objekta adrese
laukā. Tāpēc, ka abi Darbinieks
objekti atsaucas uz to pašu Adrese
objektu, mainīto pilsētu redz abi objekti.
Sastādīt 5. sarakstu (javac CloneDemo.java
) un palaidiet šo lietojumprogrammu (java CloneDemo
). Jums jāievēro šāda izeja:
Džons Doe: 49: Denvers Džons Doe: 49: Denvers Džons Doe: 49: Čikāga Džons Doe: 49: Čikāga
J: Kas ir dziļā klonēšana?
A:Dziļa klonēšana (zināms arī kā dziļa kopēšana) ir objekta lauku dublēšanās tā, ka visi atsauces objekti tiek dublēti. Turklāt viņu atsauces objekti tiek dublēti - un tā tālāk. Piemēram, 6 refaktoru uzskaitījums 5. saraksts, lai piesaistītu dziļu klonēšanu. Tas arī parāda kovariānos atgriešanās veidus un elastīgāku klonēšanas veidu.
Uzskaitīšana 6. Dziļi klonējot adrese
laukā
klase Darbinieks ievieš Cloneable {private String name; privāts int vecums; privātā adreses adrese; Darbinieks (virknes nosaukums, vecums, adreses adrese) {this.name = vārds; tas.vecums = vecums; this.adress = adrese; } @Orride public Employee clone () izmet CloneNotSupportedException {Employee e = (Employee) super.clone (); e.adrese = adrese.klons (); atgriešanās e; } Adrese getAddress () {atgriešanās adrese; } String getName () {atgriešanās nosaukums; } int getAge () {atgriešanās vecums; }} klases adrese {private String city; Adrese (virknes pilsēta) {this.city = city; } @Orride public Address clone () {return new Address (new String (city)); } Virkne getCity () {atgriešanās pilsēta; } void setCity (virknes pilsēta) {this.city = pilsēta; }} public class CloneDemo {public static void main (String [] args) izmet CloneNotSupportedException {Employee e = new Employee ("John Doe", 49, new Address ("Denver")); System.out.printf ("% s:% d:% s% n", e.getName (), e.getAge (), e.getAddress (). GetCity ()); Darbinieks e2 = (Darbinieks) e.klons (); System.out.printf ("% s:% d:% s% n", e2.getName (), e2.getAge (), e2.getAddress (). GetCity ()); e.getAddress (). setCity ("Čikāga"); 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 ()); }}
6. saraksts izmanto Java atbalstu kovariētiem atgriešanās veidiem, lai mainītu atgriešanās veidu Darbinieks
ir svarīgāks klons ()
metode no Objekts
uz Darbinieks
. Priekšrocība ir tā, ka kods ir ārpus Darbinieks
var klonēt Darbinieks
objektu bez nepieciešamības mest šo objektu Darbinieks
tips.
Darbinieks
's klons ()
metodi vispirms izsauc super.klons ()
, kas sekli kopē nosaukums
, vecums
, un adrese
lauki. Pēc tam tā atsaucas klons ()
uz adrese
lauks, lai izveidotu atsauces dublikātu Adrese
objekts.
The Adrese
klase ignorē klons ()
metodi un atklāj dažas atšķirības no iepriekšējām klasēm, kas ignorē šo metodi:
Adrese
neieviešKlonējams
. Tas nav nepieciešams, jo tikaiObjekts
'sklons ()
metode prasa, lai klase ieviestu šo saskarni, un tasklons ()
metode netiek izsaukta.- Galvenais
klons ()
metode nemetCloneNotSupportedException
. Šis pārbaudītais izņēmums tiek izmantots tikai noObjekts
'sklons ()
metodi, kas netiek izsaukta. Tāpēc izņēmums nav jāapstrādā vai jāpārvieto pa metodi izsaukuma kaudzi, izmantojot metienu klauzulu. Objekts
'sklons ()
metode netiek izsaukta (navsuper.klons ()
zvans), jo sekla kopēšana nav nepieciešamaAdrese
klase - kopējams tikai viens lauks.
Lai klonētu Adrese
objekts, pietiek ar jauna izveidošanu Adrese
objektu un inicializējiet to objekta dublikātā, uz kuru atsaucas pilsēta
laukā. Jauno Adrese
objekts tiek atgriezts.