úterý 14. října 2008

Záludnost jménem clone

Dneska jsem s hrůzou v očích zjistil, že jsem měl základní nedostatek v tom, jak by se měla správně překrývat metoda clone(). Psát zde, že i mistr tesař se někdy utne, není na místě, protože se rozhodně za mistra nepovažuji. Pojdmě se tedy podívat na to kde leží zakopaný pes.


public class A implements Cloneable{
 @Override
 protected Object clone() throws CloneNotSupportedException {  
  return new A();
 } 
}


public class B extends A implements Cloneable {
 @Override
 protected Object clone() throws CloneNotSupportedException {  
  return (B) super.clone();
 } 
}

Problém leží v překryté metodě clone třídy A, protože ta nepoužívá metodu clone předka (java.lang.Object#clone). Tato metoda na java.lang.Object totiž zaručí, že vnikně právě kopie objektu, na kterém byla volána.

Správně tedy:


        @Override
 protected Object clone() throws CloneNotSupportedException {  
  Object clone = super.clone();
                assert clone instanceof A;
                return clone;
 } 

Když toto chování nedodržíme ve všech třídách, pak nám dojde k ClassCastException. Dobré to vědět! Skoro se stydím označit tento spot štítkem pro-zacatecniky.