首頁  >  問答  >  主體

Java类中为什么不能直接调用Object的clone()方法

在Java中所有的类都是Object的子类。

在Object类中有一个clone方法定义如下:

protected native Object clone() throws CloneNotSupportedException;

该方法的修饰符为protected,表示该方法可以在子类中调用


然后结果是调用不了

网上有回答是需要实现Cloneable接口,但即使实现了,也调用不到。
不实现Cloneable接口,只是报CloneNotSupportedException异常。

只能重写clone方法,并且使用super.clone()

疑惑这是为什么呢?

黄舟黄舟2711 天前1035

全部回覆(5)我來回復

  • 巴扎黑

    巴扎黑2017-04-18 10:18:27

    Cloneable介面只是個標誌,他裡面是空的
    Object的clone方法是本地方法,比較有效率
    使用clone方法的幾個條件

    1)在派生类中实现Cloneable借口。
    

      2)為了取得物件的一份拷貝,我們可以利用Object類別的clone方法。

      3)在衍生類別中覆寫累積的clone方法,宣告為public。

      4)在衍生類別的clone方法中,呼叫super.clone()。

    再具體的可以參考
    http://www.cnblogs.com/gw811/...

    回覆
    0
  • PHPz

    PHPz2017-04-18 10:18:27

    可以呼叫啊:

    public class Test implements Cloneable{
        private int foo;
    
        public Test(int foo) {
            this.foo = foo;
        }
    
        @Override
        protected Object clone() throws CloneNotSupportedException {
            return super.clone();
        }
    
        public int getFoo() {
            return foo;
        }
    
        public static void main(String[] args) throws CloneNotSupportedException {
            Test test = new Test(1);
            Test cloned = (Test) test.clone();
            System.out.println(cloned.getFoo());
        }
    }

    回覆
    0
  • 怪我咯

    怪我咯2017-04-18 10:18:27

    clone() 是protected的作用域。繼承Cloneable介面後要重寫方法,然後在方法裡呼叫父類別的clone()的方法。同時預設的克隆對於引用物件只是淺克隆。給你一段程式碼自己去運行試試看:

    package cesar.Test0810;
    
    /**
     * Created by Cesar on 2016/8/10.
     */
    public class A implements Cloneable{
    
        private int a;
        private B b;
    
        public int getA() {
            return a;
        }
    
        public void setA(int a) {
            this.a = a;
        }
    
        public B getB() {
            return b;
        }
    
        @Override
        public String toString() {
            return "A{" +
                    "a=" + a +
                    ", b=" + b +
                    '}';
        }
    
        public void setB(B b) {
            this.b = b;
        }
    
        protected A clone() throws CloneNotSupportedException {
            return (A) super.clone();
        }
    }
    
    package cesar.Test0810;
    
    /**
     * Created by Cesar on 2016/8/10.
     */
    public class B {
    
        private int b1;
        private int b2;
    
        @Override
        public String toString() {
            return "B{" +
                    "b1=" + b1 +
                    ", b2=" + b2 +
                    '}';
        }
    
        public B(int b1, int b2){
            this.b1 = b1;
            this.b2 = b2;
        }
    
        public int getB1() {
            return b1;
        }
    
        public void setB1(int b1) {
            this.b1 = b1;
        }
    
        public int getB2() {
            return b2;
        }
    
        public void setB2(int b2) {
            this.b2 = b2;
        }
    }
    package cesar.Test0810;
    
    /**
     * Created by Cesar on 2016/8/10.
     */
    public class TestClone {
    
        public static void main(String[] args) {
    
            A a = new A();
            B b = new B(1, 2);
    
            a.setA(10);
            a.setB(b);
            try {
                A a1 = a.clone();
                System.out.println("a=" + a.toString());
                System.out.println("a1=" + a1.toString());
    
                a.setA(1000);
                a.getB().setB1(10000);
                a.getB().setB2(8000);
    
                System.out.println("a=" + a.toString());
                System.out.println("a1=" + a1.toString());
    
                a.setB(new B(9999,9999));
    
                System.out.println("a=" + a.toString());
                System.out.println("a1=" + a1.toString());
    
    
            } catch (CloneNotSupportedException e) {
                e.printStackTrace();
            }
        }
    }
    
    • 其中A繼承了cloneable接口,同時持有了對B的引用。

    回覆
    0
  • PHP中文网

    PHP中文网2017-04-18 10:18:27

    實作介面Cloneable,重寫clone()方法。

    回覆
    0
  • 天蓬老师

    天蓬老师2017-04-18 10:18:27

    剛剛看我也很疑惑,試了一下,發現是直接呼叫object中的clone方法的。
    程式碼如下:

    public class CommonTest implements Cloneable{

    public static String name  = "hell0";
    public static void main(String[] args){
    
        try{
            CommonTest aa = new CommonTest();
            CommonTest ee = (CommonTest) aa.clone();
            System.out.println("Clone succeed");
            System.out.println(ee.name);
        }catch (CloneNotSupportedException e) {
            System.out.print("clone failed");
        }
    }

    }

    回覆
    0
  • 取消回覆