Klon (metoda Java) - Clone (Java method)
Tento článek obsahuje seznam obecných Reference, ale zůstává z velké části neověřený, protože postrádá dostatečné odpovídající vložené citace.Srpna 2010) (Zjistěte, jak a kdy odstranit tuto zprávu šablony) ( |
klon ()
je metoda v Programovací jazyk Java pro duplikace objektu. V Javě jsou objekty manipulovány prostřednictvím referenčních proměnných a pro operátor neexistuje žádný operátor kopírování objekt — operátor přiřazení duplikuje referenci, ne objekt. Metoda clone () poskytuje tuto chybějící funkci.
Přehled
Třídy, které chtějí kopírovací funkce, musí k tomu implementovat nějakou metodu. Do jisté míry tuto funkci poskytuje „Object.clone ()
".
klon ()
chová se jako konstruktor kopie. Typicky to volá klon ()
metoda své nadtřídy k získání kopie atd., dokud nakonec nedosáhne Objekt
je klon ()
metoda. Speciální klon ()
metoda v základní třída Objekt
poskytuje standardní mechanismus pro duplikování objektů.
The třída Objekt
je klon ()
metoda vytvoří a vrátí kopii objektu se stejnou třídou a se všemi poli se stejnými hodnotami. Nicméně, Object.clone ()
hodí a CloneNotSupportedException
pokud objekt není instancí třídy, která implementuje značkovací rozhraní Cloneable
.
Výchozí implementace Object.clone ()
provádí a mělká kopie. Když třída touží a hluboká kopie nebo jiné vlastní chování, musí to implementovat ve svém vlastním klon ()
poté, co získali kopii ze supertřídy.
Syntaxe pro volání klon
v Javě je (za předpokladu obj
je proměnná typu třídy, která má public klon ()
metoda):
Objekt kopírovat = obj.klon();
nebo běžně
Moje třída kopírovat = (Moje třída) obj.klon();
který poskytuje obsadit potřeba přiřadit generála Objekt
reference vrácena z klon
k odkazu na a Moje třída
objekt.
Jedna nevýhoda s designem klon ()
metoda je, že návratový typ klon ()
je Objekt
a musí být explicitně vrženo zpět do příslušného typu. Avšak převažující klon ()
je vhodnější vrátit vhodný typ a eliminuje potřebu casting v klientovi (pomocí kovarianční návratové typy, od J2SE 5.0).
Další nevýhodou je, že člověk často nemá přístup k internetu klon ()
metoda na abstraktním typu. Většina rozhraní a abstraktních tříd v Javě neurčuje veřejnost klon ()
metoda. Jako výsledek, často klon ()
metodu lze použít pouze v případě, že je známa skutečná třída objektu, což je v rozporu s abstrakčním principem používání nejobecnějšího možného typu. Například pokud má jeden a Seznam
odkaz v Javě, nelze vyvolat klon ()
na tomto odkazu, protože Seznam
neurčuje žádnou veřejnost klon ()
metoda. Skutečné implementace Seznam
jako ArrayList
a Spojový seznam
všichni obecně mají klon ()
samotné metody, ale je nepohodlné a špatné abstrakce nosit skutečný typ třídy objektu.
Alternativy
Existují alternativy k klon ()
, zejména použití a kopírovací konstruktor - konstruktor, který jako parametr přijímá jinou instanci stejné třídy - nebo tovární metoda. Tyto metody nejsou vždy adekvátní, pokud není předem znám konkrétní typ klonovaného objektu. (Nicméně, klon ()
často není adekvátní ani ze stejného důvodu, protože většina abstraktních tříd neimplementuje veřejnost klon ()
metoda.)
Alternativou k použití klonu je také použití serializace a deserializace.
Singleton vzor
Při psaní kurzu pomocí Singleton vzor, najednou může existovat pouze jedna instance této třídy. Výsledkem je, že třídě nesmí být dovoleno vytvořit klon. Aby se tomu zabránilo, lze přepsat klon ()
metoda pomocí následujícího kódu:
veřejnost Objekt klon() hodí CloneNotSupportedException { házet Nový CloneNotSupportedException();}
To je nutné pouze v případě, že nadtřída implementuje veřejnost klon ()
nebo zabránit tomu, aby podtřída používala tuto třídu klon ()
způsob získání kopie. Třídy obvykle nedědí veřejnost klon ()
metoda protože Objekt
nemá veřejnost klon ()
metoda, takže je obvykle zbytečné explicitně implementovat nefunkční klon ()
metoda.
Hierarchie tříd
Chcete-li poskytnout správně klonovatelný objekt jakéhokoli typu, musí být metoda clone () správně deklarována a správně implementována podle konvence popsané v Object.clone ().
1) Každý typ, který je třeba klonovat, musí mít ve své třídě veřejnou metodu clone () nebo metodu veřejně přístupné clone () v jedné ze svých nadřazených tříd.
Příklad:
Chcete-li vyvolat clone () na varY1, který je typu Y, pak Y nebo rodič Y musí deklarovat veřejně přístupnou metodu clone (). Tady je to nadřazená třída X, která poskytuje metodu public clone ().
veřejnost třída X nářadí Cloneable { veřejnost X klon() hodí CloneNotSupportedException { vrátit se (X) super.klon(); }}veřejnost třída Y rozšiřuje X { }veřejnost třída Z rozšiřuje Y { }veřejnost třída test1 { veřejnost prázdnota funkce() hodí CloneNotSupportedException { Y varY1 = Nový Z(); Y varY2 = (Y) varY1.klon(); }}
2) Každá třída, která implementuje clone (), by měla volat super.clone (), aby získala odkaz na klonovaný objekt. Pokud má třída jakékoli odkazy na objekty, které musí být také klonovány (například při hlubokém kopírování), měla by metoda clone () provést všechny požadované úpravy objektu před jeho vrácením. (Protože Object.clone () vrací přesnou kopii původního objektu, veškerá proměnlivá pole, jako jsou kolekce a pole, by byla sdílena mezi originálem a kopií - což by ve většině případů nebylo ani očekáváno, ani žádoucí.)
Příklad:
Protože třída Z obsahuje odkaz na objekt, její metoda clone () také klonuje tento odkaz na objekt, aby vrátila hlubokou kopii originálu.
veřejnost třída X nářadí Cloneable { veřejnost X klon() hodí CloneNotSupportedException { vrátit se (X) super.klon(); }}veřejnost třída Y rozšiřuje X { }veřejnost třída ObjectABC nářadí Cloneable { veřejnost ObjectABC klon() hodí CloneNotSupportedException { vrátit se (ObjectABC) super.klon(); }}veřejnost třída Z rozšiřuje Y { soukromé ObjectABC některéABC; veřejnost Z klon() hodí CloneNotSupportedException { Z novýZ = (Z) super.klon(); novýZ.některéABC = některéABC.klon(); vrátit se novýZ; }}veřejnost třída test1 { veřejnost prázdnota funkce() hodí CloneNotSupportedException { Y varY1 = Nový Z(); Y varY2 = (Y) varY1.klon(); }}
Úskalí
Pokud každá třída v hierarchii implementuje a klon ()
metoda, všechny tyto funkce budou vyvolány při klonování a přidáním nějaké režie. Během mnoha iterací by se tato režie mohla stát významnou.
U grafů složitých objektů může být hluboké kopírování také problematické, pokud existují rekurzivní odkazy.
Není vždy vhodné mít kolem sebe více kopií stejného objektu. Pokud je účel konkrétního klon ()
implementace není plně pochopena spotřebiteli, může neúmyslně narušit paradigma „jeden objekt, více odkazů“.
Závěrečná pole
Obvykle, klon ()
je nekompatibilní s finále
pole. Protože klon ()
je v podstatě výchozí konstruktor (ten, který nemá žádné argumenty), je nemožné přiřadit a finále
pole v rámci klon ()
metoda; výsledkem je chyba kompilátoru. Kde je hodnota pole an neměnný objekt to je v pořádku; jen nechte 'konstruktor' zkopírovat odkaz a originál i jeho klon budou sdílet stejný objekt.
Ale kde je hodnota proměnlivý objekt, musí být hluboce zkopírován. Jedním z řešení je odstranění finále
modifikátor z pole, vzdávající se výhod, které mu modifikátor udělil.
Z tohoto důvodu někteří programátoři navrhují vytvořit objekty v hierarchii Serializovatelné a vytvářet kopie serializací starého objektu a poté vytvořením nového objektu z výsledného bitový proud, který zpracovává konečné datové členy správně, ale je výrazně pomalejší.[1]
Alternativně lze z aktuálních polí objektů vrátit zcela nový objekt, který lze provést nejprve voláním konstruktoru a později přiřazením ne finálních polí. Další alternativní metodou je ve skutečnosti formalizace myšlenky: vytvoření konstruktoru kopie, který přebírá instanci. To je ve skutečnosti to, co někteří lidé doporučují při klonování.[2]
Reference
- ^ Miller, Dave (6. srpna 1999). „Java Tip 76: Alternativa k technice hlubokého kopírování“. JavaWorld. Citováno 2020-07-14.
- ^ Clone () vs Copy konstruktor - který se doporučuje v Javě, Přetečení zásobníku
externí odkazy
- McManus, Eamonn (4. dubna 2007). "Klonování objektů Java pomocí serializace". Blog Eamonna McManuse. java.net. Archivovány od originál 13. srpna 2010. Citováno 2010-11-16.
- Bloch, Joshua (2008). Efektivní Java: Průvodce programovacím jazykem. Řada Java (2. vydání). Addison-Wesley. ISBN 0-321-35668-3.
- „Vyhnout se klonování“. Shromážděné postupy Java. Hirondelle Systems. 2009. Citováno 2009-07-31.
- „Object (Java Platform SE 6)“. Java Platform Standard Ed. 6. Sun Microsystems, Inc. 2008. Citováno 2009-07-31.
- Roulo, Mark (1. ledna 1999). "Jak se vyhnout pasti a správně přepsat metody z java.lang.Object". JavaWorld. Citováno 2020-07-14. - Zahrnuje základy implementace metody klonování.
- Výukový program pro klonování Java.