2013-03-22 7 views
6

Jest coś, czego nie rozumiem w zwykłej realizacji metody klonowania. Jeśli przyjrzeć się pierwszemu wierszowi w bloku try w poniższym kodzie, wywołujemy super.clone(), który utworzy instancję super klasy i zwróci odwołanie do obiektu do tej instancji. Teraz ta instancja niekoniecznie zawiera leaseDay, więc jak nam się mówi copy.hireDay? To prawda, że ​​skompiluje się dobrze, ale czy nie powinien się zawiesić, jeśli instancja nie zawiera leaseDay?W clone() używamy super.clone(), a następnie dostęp do zmiennej, która nie jest w super, jak przychodzi?

public Object clone() { 
    try { 
     Employee copy = (Employee) super.clone(); // copy ID, name, and salary! 
     copy.hireDay = (Date) hireDay.clone(); 
     return copy; 
    } catch (CloneNotSupportedException e) { 
     System.out.println(e); 
     return null; 
    } 
} 

Odpowiedz

3

Kontrakt z clone polega na uzyskaniu tego samego wzorca wywołań, co w przypadku konstruktorów: pierwszym krokiem jest zawsze wywołanie implementacji nadklasy. Powoduje to, że najpierw wywoływane jest Object.clone, a wszystkie podklasy używają instancji zwróconej przez tę metodę.

Object.clone zwróci instancję tej samej klasy co sklonowana. Dzieje się tak za sprawą magii pozajęzykowej, zasadniczo przez bitową kopię bloku pamięci + niezbędne zmiany w kopii.

Mechanizm klonowania jest delikatny, ponieważ każda niezgodna klasa w łańcuchu przodków przerywa klonowanie dla wszystkich jego potomków. Jest to jeden z kilku powodów, dla których ten mechanizm jest nieuczciwy.

+0

Czy możesz podać przykład klasy niezgodnej w łańcuchu przodków (najlepiej związanej z klasą Pracownika). Co jest lepszym mechanizmem niż klonowanie? –

+1

Każda klasa, która nie zwraca instancji uzyskanej z 'super.clone()' jest niezgodna. –

+0

Dobrze, więc zawsze musimy zadzwonić do super.clone(). Czy istnieje lepszy mechanizm niż klonowanie? –

3

clone() to specjalna metoda w klasie bazowej Object który tworzy nową instancję klasy bazowej prawidłowego rodzaju i kopie wszystkich dziedzinach (i unika stosowania jakichkolwiek konstruktorów). Tak więc, pod warunkiem, że nie masz niestandardowej klasy nadrzędnej, która ma , a nie delegować do Object.clone(), zawsze otrzymasz bieżący typ z powrotem.

Na marginesie, w przykładzie, jeśli super.clone() zrobił nie zwróci Employee, wtedy kod będzie rzucać ClassCastException zanim jeszcze dostał się do etapu, w którym odwoływać hireDay.

+0

Co masz na myśli przez "nie deleguje do Object.clone()"? –

Powiązane problemy