You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何调用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 08:01:02