Mandatory cloneable interface in Java

后端 未结 6 1597
北恋
北恋 2021-01-06 09:01

I\'m having a small problem in Java. I have an interface called Modifiable. Objects implementing this interface are Modifiable.

I also have a ModifyCommand class (wi

相关标签:
6条回答
  • 2021-01-06 09:37

    Adding to Sean Reilly's answer, this should solve your problem, and is more type safe. It compiles and runs fine with me on JDK6:

    public interface Modifiable<T extends Modifiable<T>> extends Cloneable {
        T clone();
    }
    public class Test implements Modifiable<Test> {
        @Override
        public Test clone() {
            System.out.println("clone");
            return null;
        }
        public static void main(String[] args) {
            Test t = new Test().clone();
        }
    }
    

    I couldn't test it with Java 5 because I don't have it installed, but I guess it would work fine.

    0 讨论(0)
  • 2021-01-06 09:49

    Did you define the signature exactly as it is in object?

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

    This should compile - add custom code to the body. Wikipedia was surprisingly helpful on this one.

    0 讨论(0)
  • 2021-01-06 09:52

    You don't need to redefine the clone method on the interface Modifiable.

    Check the documentation: http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Cloneable.html

    I understand that you are trying to force everyone to override clone method(), but you can't do it.

    In another way, you cannot override a class on a interface:

    The clone() method is always associated whit the Object.class and not the cloneable interface. You just can override it on another object, not in a interface.

    0 讨论(0)
  • 2021-01-06 09:59

    If you're using java 1.5 or higher, you can get the behavior you want and remove casting this way:

    public interface Modifiable<T extends Modifiable<T>> extends Cloneable {
        T clone();
    }
    
    public class Foo implements Modifiable<Foo> {
        public Foo clone() { //this is required
            return null; //todo: real work
        }
    }
    

    Since Foo extends Object, this still satisfies the original contract of the Object class. Code that doesn't refine the clone() method correctly will not compile, because of the additional constraints imposed by the Modifiable interface. As a bonus, calling code doesn't have to cast the result of the clone method.

    0 讨论(0)
  • 2021-01-06 10:02

    What does your method signature for your clone method look like? For it to match the Clonable interface it would have to return an Object. If you're declaring it as returning a Modifiable then that could be the problem.

    0 讨论(0)
  • 2021-01-06 10:03

    public class CloningExample implements Cloneable {

    private LinkedList names = new LinkedList();
    
    
    public CloningExample() {
        names.add("Alex");
        names.add("Melody");
        names.add("Jeff");
    }
    
    
    public String toString() {
        StringBuffer sb = new StringBuffer();
        Iterator i = names.iterator();
        while (i.hasNext()) {
            sb.append("\n\t" + i.next());
        }
        return sb.toString();
    }
    
    
    public Object clone() {
        try {
            return super.clone();
        } catch (CloneNotSupportedException e) {
            throw new Error("This should not occur since we implement Cloneable");
        }
    }
    
    
    public Object deepClone() {
        try {
            CloningExample copy = (CloningExample)super.clone();
            copy.names = (LinkedList)names.clone();
            return copy;
        } catch (CloneNotSupportedException e) {
            throw new Error("This should not occur since we implement Cloneable");
        }
    }
    
    public boolean equals(Object obj) {
    
        /* is obj reference this object being compared */
        if (obj == this) {
            return true;
        }
    
        /* is obj reference null */
        if (obj == null) {
            return false;
        }
    
        /* Make sure references are of same type */
        if (!(this.getClass() == obj.getClass())) {
            return false;
        } else {
            CloningExample tmp = (CloningExample)obj;
            if (this.names == tmp.names) {
                return true;
            } else {
                return false;
            }
        }
    
    }
    
    
    public static void main(String[] args) {
    
        CloningExample ce1 = new CloningExample();
        System.out.println("\nCloningExample[1]\n" + 
                           "-----------------" + ce1);
    
        CloningExample ce2 = (CloningExample)ce1.clone();
        System.out.println("\nCloningExample[2]\n" +
                           "-----------------" + ce2);
    
        System.out.println("\nCompare Shallow Copy\n" +
                           "--------------------\n" +
                           "    ce1 == ce2      : " + (ce1 == ce2) + "\n" +
                           "    ce1.equals(ce2) : " + ce1.equals(ce2));
    
        CloningExample ce3 = (CloningExample)ce1.deepClone();
        System.out.println("\nCompare Deep Copy\n" +
                           "--------------------\n" +
                           "    ce1 == ce3      : " + (ce1 == ce3) + "\n" +
                           "    ce1.equals(ce3) : " + ce1.equals(ce3));
    
        System.out.println();
    
    }
    

    }

    0 讨论(0)
提交回复
热议问题