7

特定のオブジェクトのクローンを作成したい。

私がこれをしたら

public class Something{
    Object o; //set in the constructor
    public Something(Object o){
         this.o = o;}
    public Something clone() throws CloneNotSupportedException{
         Something temp = super.clone();
         if (o instanceof Cloneable) //important part
             temp.o = o.clone(); //important part
         else temp.o = o;
    }
}

o.clone() が保護されているため、これは機能しません。

代わりにこれを行うと

         if (o instanceof Cloneable) //important part
             temp.o = ((Cloneable)o).clone(); //important part

Cloneable は空のインターフェースであるため、どちらも機能しません。

では、クローンを作成できることをコンパイラに納得させるにはどうすればよいでしょうか?

4

5 に答える 5

2

Serializable インターフェイスを実装できる場合は、シリアライゼーションを使用することもできます。欠点はもちろんパフォーマンスです。

https://commons.apache.org/proper/commons-lang/javadocs/api-2.6/org/apache/commons/lang/SerializationUtils.html#clone(java.io.Serializable)

Apache Commons を使用したくない場合は、ObjectOutputStream/ObjectInputStream を使用して同じことを行うことができます。

于 2015-06-21T12:10:00.780 に答える
1

あなたは反射でそれを行うことができます

//We need reflection
import java.lang.reflect.*;
    //This class is the backbone of the feature
    public class MyCloneable implements Cloneable {

        //A constructor. For the sake of simplicity, the constructor is an empty constructor.
        public MyCloneable() {}

        //We implement the clone method. This returns a clone
        protected Object clone() throws CloneNotSupportedException {
            //We need the class of the object
            class c = this.getClass();
            //We get the empty constructor of the object
            Constructor constructor = c.getConstructor(new Class[]{});
            //newClone will be the cloned object
            Object newClone = constructor.newInstance(new Object[]{});
            //We get the array of fields
            Field[] fields = c.getDeclaredFields();
            //We iterate the fields to copy them. You might want to close these too, but for the sake of simplicity I did not tackle with this issue
            for (int fieldIndex = 0; fieldIndex < fields.length; fieldIndex++) {
                //We copy the field values of this into the clone
                fields[fieldIndex].set(newClone, fields[fieldIndex].get(this));
            }
            //newClone is ready and kicking
            return newClone;
        }

        //We need this method to be able to reach the clone method publicly
        public Object runClone() throws CloneNotSupportedException {
            return this.clone();
        }

    }

このコードはテストされていません。

MyCloneable から継承されたクラスのオブジェクトを使用する必要があります。

于 2015-06-21T12:31:15.937 に答える
0

Java でオブジェクトを複製する一般的な方法はありません。型は、そのパブリック API でクローンを作成するメソッドを提供する必要があります (これは、呼び出されるclone()か、または別のものである可能性があります。問題ではありません)。Java には、そのような型に共通のスーパータイプはありません。

于 2015-06-23T01:24:17.290 に答える
-1

インターフェイスは、java.lang.Cloneable作成するオブジェクトのクローンを持つクラスによって実装される必要があります。Cloneable インターフェイスを実装しない場合、clone()メソッドは を生成しCloneNotSupportedExceptionます。

clone()メソッドは Object クラスで定義されます。メソッドの構文は次のclone()とおりです。

protected Object clone() throws CloneNotSupportedException

したがって、クラスは次のようになります

public class Something implements Cloneable {

    private Object o; //set in the constructor

    public Something(Object o) {
        this.o = o;
    }

    @Override
    public Object clone() throws CloneNotSupportedException {
        return super.clone();
    }

    public Object getObject() {
        return o;
    }

    public static void main(String[] args) {
        Something s = new Something("try");
        System.out.println(s.getObject());
        try {
            Something s2 = (Something) s.clone();
            System.out.println(s2.getObject());
        } catch (CloneNotSupportedException ex) {
            Logger.getLogger(Something.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}
于 2015-06-21T12:13:51.293 に答える