2011-07-07 3 views
1

J'ai un programme simple pour cloner un objet, j'ai googlé l'erreur "Exception dans le fil" principal "java.lang.CloneNotSupportedException:" mais besoin de votre aide pour comprendre l'erreur, pourquoi je ne suis pas capable de obtenir un clone d'obj1?Impossible de comprendre le clone

public class Test{ 
int a; 
int b; 
public Test(int a , int b){ 
    this.a=a; 
    this.b=b; 
    } 
public static void main(String[]args) throws CloneNotSupportedException{ 
    Test obj1=new Test(2, 4); 
    Test obj2=(Test) obj1.clone(); 
     } 
} 
+0

Je vous conseille de ne pas utiliser le paradigme clone, il est très difficile d'obtenir le droit. Faites-vous une faveur et passez à copier des constructeurs. Voir aussi: http://www.javapractices.com/topic/TopicAction.do?Id=71 –

Répondre

4

Le problème se produit parce que la classe Test ne met pas en oeuvre l'interface Cloneable. Comme indiqué dans le API specs,

si la classe [..] ne met pas en œuvre l'interface Cloneable, puis un CloneNotSupportedException est jeté.

Pour fixer, essayer quelque chose comme:

public class Test implements Cloneable { 
    ... 
} 

Depuis l'interface Cloneable déclare aucune méthode (il est appelé une interface marqueur , tout comme Serializable), il n'y a plus rien à faire. Les instances de votre classe Test peuvent maintenant être clonées. Toutefois, le mécanisme de clonage par défaut (c'est-à-dire celui de Object) peut ne pas correspondre exactement à ce que vous recherchez et vous pouvez remplacer la méthode clone(). La valeur par défaut est de faire une copie superficielle, c'est-à-dire que vous obtiendrez une nouvelle instance distincte de votre classe, mais les champs des deux instances se référeront aux mêmes objets! Par exemple:

class C1 { 
    Object o; 
} 
class C2 implements Cloneable { 
    C1 c1; 
} 

... main ... { 
    C2 c2 = new C2(); 
    c2.c1 = new C1(); 
    c2.c1.o = new Object(); 
    C2 c2clone = c2.clone(); 
    System.out.println(c2 == c2clone); // prints false 
    System.out.println(c2.c1 == c2clone.c1); // prints true 
    c2.c1.o = new Object(); // modified both c2 and c2clone!!! 

La dernière ligne modifier à la fois c2 et c2clone parce que les deux points à la même instance de c1. Si vous voulez que la dernière ligne ne modifie que c2, alors vous devez faire ce que nous appelons une copie profonde .

+0

Oui cela a fonctionné merci, répondez s'il vous plaît, si nous avons implémenté l'interface Cloneable, laquelle des méthodes dans Cloneable est-ce que nous définissons/écrasons dans notre classe? –

+1

L'interface 'Cloneable' n'a pas de méthodes. C'est juste un marqueur, tout comme 'Serializable'. –

+1

@helloMaga: aucun. 'Cloneable' n'a pas de méthodes. Comme @cmv l'a mentionné, c'est une interface de marqueur pure (c'est-à-dire que son existence a une signification, elle ne vous force pas à implémenter certaines méthodes). Une autre interface de marqueur commune est Serializable. Les interfaces de marquage ne sont généralement pas considérées comme un très bon design, mais elles existent. –

2

Vous devez implémenter Cloneable. C'est une interface de marqueur.

Votre programme devrait être

public class Test implements Cloneable{ 
     //rest of the program 
    } 
+0

si nous avons implémenté l'interface Cloneable, laquelle des méthodes de Cloneable définissons-nous/surpassons-nous dans notre classe? Cloneable –

+1

est une interface de marqueur. Il n'a pas de méthodes. – vinoth

+0

S'il n'y a pas de méthode déclarée dans une interface, pourquoi un développeur en at-il besoin? Pourquoi est-ce dans Java Docs? pourquoi devrions-nous même l'implémenter? Si c'est quelque chose comme - interface MarkerExampl {}, alors je ressens son gaspillage d'espace et de temps. S'il vous plaît, éduquez moi. –

Questions connexes