猿问

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

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

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

protected native Object clone() throws CloneNotSupportedException;

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


然后结果是调用不了

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

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

疑惑这是为什么呢?


慕森卡
浏览 3415回答 5
5回答

weixin_慕村3541823

我想我明白你问的是什么。举个例子:clone()方法是Object里面的protected方法,只允许在同包和子类内部调用。现在有一个类Cat,默认继承Object,所以假如你的调用测试写在Cat类里面,那么是可以调用的。但是假如你在和Cat同包的下面写了一个Test测试类,并尝试在Test里面实例化Cat,并调用clone(),是无法调用的。原因是,假如Cat没有重写clone()方法,Cat调用的clone()方法是Object类的,而Test类和Object不同包。你可能会问Test也是Object的子类呀?是的没错,你可以在子类内部调用自己的clone()方法,但是你不可以调用你兄弟类的clone()方法,protected的语义就是这样的。

慕婉清6304310

protected方法在子类中可调用特指通过对应子类对象调用 而不是父类的其他子类的对象或父类对象 lz的例子就是通过在子类中通过父类的其他子类的对象调用父类的protected方法,所以编译通过不了 我一开始也没弄清楚有跟lz一样的疑问 纳闷了好久

aluckdog

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的引用。

陪伴而非守候

实现接口Cloneable,重写clone()方法。

慕姐8265434

实现了Cloneable接口如果不重写clone方法,将clone方法的权限等级上升到public,因为继承下来的clone是protected权限,那么clone方法只能在子类调用,不能被外部类调用。
随时随地看视频慕课网APP

相关分类

Java
我要回答