Clone () vs Copy constructor-co jest zalecane w Javie [duplicate]

To pytanie ma już odpowiedź tutaj:

Metoda klonowania vs Konstruktor kopiujący w Javie. które z nich jest poprawnym rozwiązaniem. gdzie korzystać z każdego przypadku?

Author: Jason Nichols, 2010-03-11

6 answers

Klon jest uszkodzony, więc nie używaj go.

Metoda klonowania klasy obiektowej jest nieco magiczną metodą, która czego nie potrafi Żadna czysta metoda Javy do: produkuje identyczną kopię jego obiekt. Jest obecny w primordial Object superclass since the Beta - dni wydania Javy kompilator*; i to, jak wszystkie starożytne magii, wymaga odpowiedniego zaklęcie zapobiegające zaklęciu nieoczekiwany powrót

Preferuj metodę że kopiuje obiekt

Foo copyFoo (Foo foo){
  Foo f = new Foo();
  //for all properties in FOo
  f.set(foo.get());
  return f;
}

Czytaj więcej http://adtmag.com/articles/2000/01/18/effective-javaeffective-cloning.aspx

 96
Author: Tom,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-03-11 20:09:50

Miej na uwadze, że clone() nie działa po wyjęciu z pudełka. Będziesz musiał zaimplementować Cloneable i nadpisać metodę clone() dokonującą w public.

Istnieje kilka alternatyw, które są preferowane (ponieważ metoda clone() ma wiele problemów projektowych, jak stwierdzono w innych odpowiedziach), a Konstruktor kopiujący wymagałby ręcznej pracy:

 49
Author: Bozho,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-09-02 16:23:02

Clone() został zaprojektowany z kilkoma błędami (zobacz to pytanie ), więc najlepiej tego unikać.

From Effective Java 2nd Edition , poz. 11: Override clone

Biorąc pod uwagę wszystkie problemy związane z Cloneable, można śmiało powiedzieć że inne Interfejsy nie powinny go rozszerzać, a klasy przeznaczony do dziedziczenia (poz. 17) nie powinien go realizować. Na jego wiele wad, niektórzy programiści ekspertów po prostu wybrać nigdy nie nadpisać metodę klonowania i nigdy jej nie wywoływać z wyjątkiem, być może, skopiuj tablice. Jeśli projektujesz klasę do dziedziczenia, pamiętaj, że jeśli zdecydujesz się nie dostarczać dobrze zachowywanej metody klonowania chronionego, to nie będzie możliwe, aby podklasy zaimplementowały Cloneable.

Ta książka opisuje również wiele zalet konstruktorów kopii nad Cloneable/clone.

    Nie polegają one na podatnym na ryzyko pozalingwistycznym mechanizmie tworzenia obiektów.]}
  • oni nie domagaj się nieegzekwowalnego przestrzegania cienko udokumentowanych konwencji
  • nie kolidują z prawidłowym użyciem pól końcowych
  • nie rzucają niepotrzebnych sprawdzonych WYJĄTKÓW
  • Nie wymagają odlewów.

Wszystkie standardowe zbiory mają konstruktory kopiujące. Użyj ich.

List<Double> original = // some list
List<Double> copy = new ArrayList<Double>(original);
 32
Author: Rose Perrone,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:34:39

Należy pamiętać, że Konstruktor kopiujący ogranicza typ klasy do typu konstruktora kopiującego. Rozważmy przykład:

// Need to clone person, which is type Person
Person clone = new Person(person);

To nie działa, Jeśli person może być podklasą Person (lub jeśli Person jest interfejsem). Chodzi o to, że klon może być klonowany dynamicznie w czasie wykonywania (zakładając, że klon jest poprawnie zaimplementowany).

Person clone = (Person)person.clone();

Lub

Person clone = (Person)SomeCloneUtil.clone(person); // See Bozho's answer

Teraz person może być dowolnym typem Person zakładając, że clone jest poprawnie zaimplementowane.

 18
Author: Steve Kuo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-06-24 05:08:55

Zobacz także: Jak poprawnie nadpisać metodę klonowania?. Klonowanie jest łamane w Javie, więc jest to tak trudne, Aby to zrobić dobrze, a nawet jeśli to robi nie oferuje zbyt wiele , więc nie jest to naprawdę warte zachodu.

 3
Author: polygenelubricants,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:47:18

Wielki smutek: ani Clone / clone,ani konstruktor nie są świetnymi rozwiązaniami: nie chcę znać klasy implementującej!!! (np.-mam mapę, którą chcę skopiować, używając tej samej ukrytej implementacji) po prostu chcę zrobić kopię, jeśli jest to obsługiwane. Ale, niestety, Cloneable nie ma na sobie metody clone, więc nie ma nic, do czego można bezpiecznie wpisać-cast, na którym można wywołać clone ().

Jaka jest najlepsza biblioteka "copy object", Oracle powinien być standardowym komponentem następnego wydania Javy(chyba, że już jest, gdzieś ukryty).

OczywiĹ "cie, gdyby wiÄ ™ cej bibliotek (np. - Collections) byĹ 'o niezmiennych, to zadanie" kopiowania "po prostu zniknÄ ™ Ĺ' oby. Ale wtedy zaczęlibyśmy projektować programy Javy z takimi rzeczami jak" niezmienniki klas", a nie wzorcem verdammt "bean" (stwórz zepsuty obiekt i mutuj, aż będzie dobrze [wystarczająco]).

 2
Author: Roboprog,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-09-25 03:29:23