Dlaczego metoda clone () jest chroniona w Javie.lang.Obiekt?

Jaki jest konkretny powód, że clone() jest zdefiniowany jako chroniony w java.lang.Object?

Author: Paul Bellora, 2009-07-16

11 answers

Fakt, że Clone jest chroniony jest niezwykle wątpliwy - podobnie jak fakt, że metoda clone nie jest zadeklarowana w interfejsie Cloneable.

Sprawia, że metoda jest dość bezużyteczna do robienia kopii danych, ponieważ nie można powiedzieć :

if(a instanceof Cloneable) {
    copy = ((Cloneable) a).clone();
}

Myślę, że projekt Cloneable jest obecniew dużej mierze uważany za błąd (cytat poniżej). Normalnie chciałbym móc tworzyć implementacje interfejsu Cloneable, ale niekoniecznie tworzyć interfejs Cloneable (podobne do zastosowania Serializable). Nie można tego zrobić bez refleksji:

ISomething i = ...
if (i instanceof Cloneable) {
   //DAMN! I Need to know about ISomethingImpl! Unless...
   copy = (ISomething) i.getClass().getMethod("clone").invoke(i);
}

Cytat z skuteczna Java Josha Blocha:
"interfejs Klonowalny był przeznaczony jako interfejs mixin dla obiektów reklamujących, że pozwalają na klonowanie. Niestety nie służy temu celowi ... Jest to bardzo nietypowe użycie interfejsów i nie jest to emulowane ... Aby implementacja interfejsu miała jakikolwiek wpływ na klasę, to i wszystkie jej superklasy muszą przestrzegać dość skomplikowanego, nieegzekwowalnego i w dużej mierze nieudokumentowanego protokołu"

 97
Author: oxbow_lakes,
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
2009-07-16 23:24:14

Klonowalny interfejs jest tylko znacznikiem mówiącym, że klasa może obsługiwać klon. Metoda jest chroniona, ponieważ nie należy jej wywoływać na obiekcie, można (i należy) nadpisać ją jako publiczną.

Od Słońca:

W obiekcie klasy, metoda clone() jest zadeklarowana jako chroniona. Jeśli tylko zaimplementujesz Cloneable, tylko podklasy i członkowie tego samego pakietu będą mogli wywołać clone() na obiekcie. Aby umożliwić dowolnej klasie w dowolnym pakiecie dostęp do metody clone (), musisz zastąp go i zadeklaruj jako publiczny, jak to jest zrobione poniżej. (Gdy nadpisujesz metodę, możesz uczynić ją mniej prywatną, ale nie bardziej prywatną. Tutaj, metoda protected clone () w obiekcie jest nadpisywana jako metoda publiczna.)

 24
Author: Bill K,
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
2009-07-16 16:38:54

clone jest chroniony, ponieważ jest to coś, co powinno być nadpisane tak, aby było specyficzne dla bieżącej klasy. Chociaż możliwe byłoby utworzenie publicznej metody clone, która sklonowałaby dowolny obiekt, nie byłoby to tak dobre, jak metoda napisana specjalnie dla potrzebującej jej klasy.

 7
Author: Andrew Hare,
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
2009-07-16 16:30:29

Metoda Clone nie może być bezpośrednio użyta na żadnym obiekcie, dlatego jest przeznaczona do nadpisania przez podklasę.

Oczywiście może to być publiczne i po prostu rzucić odpowiedni wyjątek, gdy klonowanie nie jest możliwe, ale myślę, że byłoby to mylące.

Sposób, w jaki klon jest teraz zaimplementowany, sprawia, że myślisz o tym, dlaczego chcesz użyć clone i jak chcesz, aby twój obiekt został sklonowany.

 4
Author: Silfverstrom,
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
2009-07-16 16:34:10

Jest chroniony, ponieważ domyślna implementacja wykonuje płytką kopię wszystkich pól (w tym prywatnych), omijając konstruktor. Nie jest to coś, do czego obiekt może być zaprojektowany w pierwszej kolejności (na przykład może śledzić utworzone instancje obiektów na wspólnej liście lub coś podobnego).

Z tego samego powodu Domyślna implementacja clone() rzuci, jeśli obiekt, na którym jest wywołana, nie zaimplementuje Cloneable. To potencjalnie niebezpieczne działanie z dalekosiężnymi konsekwencjami, dlatego autor klasy musi wyraźnie wyrazić zgodę.

 2
Author: Pavel Minaev,
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
2009-07-16 16:50:35

Z javadoc cloneable.

* By convention, classes that implement this interface (cloneable) should override 
* <tt>Object.clone</tt> (which is protected) with a public method.
* See {@link java.lang.Object#clone()} for details on overriding this
* method.

* Note that this interface does <i>not</i> contain the <tt>clone</tt> method.
* Therefore, it is not possible to clone an object merely by virtue of the
* fact that it implements this interface.  Even if the clone method is invoked
* reflectively, there is no guarantee that it will succeed.

Więc można wywołać clone na każdym obiekcie, ale to daje większość czasu Nie wyniki, które chcesz lub wyjątek. Ale jest tylko zachęcany, jeśli wdrożysz cloneable.

 2
Author: Janusz,
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
2009-07-16 17:02:49

IMHO to takie proste:

  • #clone nie może być wywoływany na obiektach nieklonowalnych, dlatego nie jest upubliczniany
  • #clone musi być wywołana przez podklasy ob Object które implementują Cloneable, aby uzyskać płytką kopię właściwej klasy

Jaki jest właściwy zakres metod, które mogą być wywoływane przez podklasy, ale nie przez inne klasy?

To protected.

Klasy implementujące Cloneable oczywiście upublicznią tę metodę, dzięki czemu można ją wywołać z innych klas.

 2
Author: Michaela Elschner,
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
2016-09-05 13:03:28

Metoda Clone() posiada wewnętrzne sprawdzenie 'instancja Cloneable or not'.W ten sposób zespół Java może pomyśleć, że ograniczy niewłaściwe użycie metody clone ().metoda clone() jest chroniona, tzn. dostępna tylko dla podklas. Ponieważ obiekt jest klasą nadrzędną wszystkich podklas, więc metoda Clone() może być używana przez wszystkie klasy, jeśli nie mamy powyższego sprawdzenia 'instancja Cloneable'. To jest powód, dla którego zespół Java mógł pomyśleć o ograniczeniu niewłaściwego użycia clone() poprzez sprawdzenie w metoda clone () 'is it instance of Cloneable'.

Stąd jakiekolwiek klasy implementujące cloneable mogą używać metody clone () klasy obiektu.

Również ponieważ został zabezpieczony, jest dostępny tylko dla tych podklas, które implementują interfejs klonowalny. Jeśli chcemy ją upublicznić, ta metoda musi zostać nadpisana przez podklasę z ich własną implementacją.

 0
Author: SARIKA,
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
2018-08-17 21:07:23

Tak, ten sam problem, który spotkałem. Ale rozwiązuję go implementując ten kod

public class Side implements Cloneable {
    public Side clone() {

        Side side = null;
        try {
            side = (Side) super.clone();
        } catch (CloneNotSupportedException e) {
            System.err.println(e);
        }
        return side;
    }
}
Tak jak ktoś wcześniej powiedział.
 -2
Author: fyhao,
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
2009-08-10 16:55:17

Cóż, również deweloperzy sun są tylko ludźmi i rzeczywiście popełnili ogromny błąd implementując metodę klonowania jako chronioną, ten sam błąd, co zaimplementowali niedziałającą metodę klonowania w ArrayList! Tak więc, ogólnie rzecz biorąc, istnieje znacznie głębsze nieporozumienie nawet doświadczonych programistów Java na temat metody klonowania.

Jednak ostatnio znalazłem szybkie i łatwe rozwiązanie, aby skopiować dowolny obiekt z całą jego zawartością, bez względu na to, jak jest zbudowany i co zawiera, zobacz mój odpowiedź tutaj: Błąd w używaniu obiektu.klon()

 -2
Author: mark,
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:17:50

Znowu Java JDK Framework pokazuje genialne myślenie:

Cloneable interface nie zawiera metody " public t clone ();", ponieważ działa bardziej jak atrybut (np. Serializowalny), który pozwala na sklonowanie instancji.

Nie ma nic złego w tym projekcie, ponieważ:

  1. Obiekt.Clone () nie zrobi tego, co chcesz z Twoją niestandardową klasą.

  2. Jeśli MyClass implementuje Cloneable = > nadpisujesz clone() za pomocą "public MyClass klon()"

  3. Jeśli masz myinterface extends Cloneable i niektóre MyClasses implementujące MyInterface: po prostu zdefiniuj "public MyInterface clone ();" w interfejsie, a każda metoda korzystająca z obiektów MyInterface będzie mogła je sklonować, bez względu na ich klasę MyClass.

 -3
Author: Victor,
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-03-18 14:40:40