为何调用Object.clone()会出现“protected访问权限”编译错误?
为什么Object的protected方法clone()无法在子类中直接调用?
Object类的clone()方法是protected权限,按说所有Java类都是Object的子类,应该能在子类里访问,但在类A中调用Object实例的clone()却出现编译错误,而自定义的protected方法在子类调用父类实例的方法却能正常编译,这两者的差异其实是Java的protected访问权限规则导致的,下面具体分析:
报错代码示例
public class A { public static void main(String[] args) { Object o = new Object(); o.clone();// 编译错误:clone() has protected access in java.lang.Object } }
可编译代码示例
public class A { protected void foo() { } }
public class B extends A { public static void main(String[] args) { A a = new A(); a.foo();// 编译正常 } }
核心原因:Java的protected访问规则
Java中protected成员的访问权限有两个核心场景:
- 同一包内的所有类:不管是否有继承关系,都能访问protected成员;
- 不同包的子类:仅能访问自身实例(或自身子类实例)中继承自父类的protected成员,不能访问父类的独立实例的protected成员。
对两个案例的具体分析
1. Object.clone()报错的原因
- Object类位于
java.lang包,自定义类A默认在自己的业务包(比如com.test),属于不同包; - 类A是Object的子类,但这里调用的是Object类的独立实例
o的clone(),不是A类自己的实例,不符合不同包子类访问protected成员的规则; - 又因为不在同一个包,也无法通过包内访问的规则调用,所以编译报错。
2. 自定义protected方法可编译的原因
你给出的代码能正常编译,是因为类A和类B在同一个包下,触发了protected权限的包内访问规则——同一包内的类不管是否继承,都能访问对方的protected成员。
如果把A和B放到不同的包中,调用new A().foo()同样会出现和Object案例一样的编译错误,这和Object的规则完全一致。
额外补充:子类正确访问Object.clone()的方式
如果想在子类中使用clone(),应该调用自身实例的clone(),并且让子类实现Cloneable接口(否则会抛出CloneNotSupportedException),比如:
public class A implements Cloneable { public static void main(String[] args) throws CloneNotSupportedException { A a = new A(); Object clone = a.clone();// 编译正常 } }
内容的提问来源于stack exchange,提问作者ChpokHead
相关产品推荐
相关产品推荐

