java.lang.Object';受保护的方法是否受子类保护?

java.lang.Object';受保护的方法是否受子类保护?,java,object,protected,Java,Object,Protected,关键字protected授予对相同包和子类()中的类的访问权 现在,每个类都有java.lang.Object作为超类() 因此,我得出结论,每个类都可以访问java.lang.Object的方法,即使它们受到保护 请看以下示例: public class Testclass { public Object getOne() throws CloneNotSupportedException { return this.clone(); } public Object get

关键字
protected
授予对相同包和子类()中的类的访问权

现在,每个类都有
java.lang.Object
作为超类()

因此,我得出结论,每个类都可以访问
java.lang.Object
的方法,即使它们受到
保护

请看以下示例:

public class Testclass { public Object getOne() throws CloneNotSupportedException { return this.clone(); } public Object getTwo() throws CloneNotSupportedException { return ((Object) this).clone(); } } 我既不明白为什么
getTwo()
没有编译,也不明白
java.lang.Object
的成员访问
getOne()
getOne()

有什么区别(关于
java.lang.Object
的成员),当你说“
((Object)this.clone()”,你通过它的超类对象访问了你自己的对象。您对对象执行了加宽转换。然后,代码尝试调用对象上的克隆

但是,正如您所注意到的,clone是一种受保护的方法,这意味着只有当您的对象位于java.lang的同一个包中时,它才能访问对象的clone方法

当您说this.clone时,您的类扩展了对象,因此由于继承,您可以通过受保护的类修饰符直接重写或使用clone。但这并不会改变对象实现

通过说((Object)yourObject),您得到的东西只能通过Object类访问。只有对象类的公共方法可以在包java.lang之外访问,因此您会得到编译时异常,因为编译器知道这一点


通过这样说.clone(),您正在调用对象的clone方法,该方法是通过对象继承得到的,现在可以调用,因为它已成为自定义子类的一部分。

如果引用它的表达式的编译时类型是您自己的类或子类,则只能访问不同包中类型的受保护成员。(其中“your”类是包含代码的类。)您自己的类也必须是最初声明方法的类型的子类

这里有一个例子;假设
Base
与所有其他类位于不同的包中:

package first;
public class Base
{
    protected void Foo() {}
}

// Yes, each class is really in its own file normally - but treat
// all the classes below as being in package "second"

package second;
public class Child extends Base
{
    public void OtherMethod(Object x)
    {
        ((Base) x).Foo(); // Invalid: Base is not Child or subclass
        ((Child) x).Foo(); // Valid: Child is Child
        ((GrandChild) x).Foo(); // Valid: GrandChild is subclass of Child
        ((OtherChild) x).Foo(); // Invalid: OtherChild is not Child or subclass
    }
}

public class GrandChild extends Child {}
public class OtherChild extends Base {}
换句话说,它允许您访问“与您相似的对象”的受保护成员

详情载于:

受保护的成员或构造函数 可以从外部访问对象 在其中声明它的包 仅由负责 该对象的实现

6.6.2.1访问受保护的成员

设C是a 声明了受保护的成员m。通道 仅允许在 C的子类S。此外,如果Id 表示实例字段或实例 方法,然后:如果访问是通过 限定名Q.Id,其中Q是 ExpressionName,则访问权限为 当且仅当 表达式Q是S或的一个子类 S.如果访问是通过现场访问 表达式E.Id,其中E是主 表达式,或通过方法调用 表达式E.Id(…),其中E是 主表达式,则访问权限为 当且仅当E的类型 是S或S的一个子类


区别在于访问Object.clone()的方式。只有通过同一软件包中的子类或类进行访问时,才能访问克隆。在getOne()示例中,您正在对这个.clone()进行分类。这显然满足了子类内部的访问


在getTwo()中,尽管您正在访问Object.clone()和notTestClass.clone()。为了使此功能正常工作,您必须拥有对对象的包级访问权限,而您没有,因此出现了错误。

您将受保护与受包保护混淆了。我不这么认为:“当您说this.clone时,您的类扩展了对象,因此由于继承,您可以通过受保护的类修饰符直接重写或使用clone”我对这句话吹毛求疵:“但是,正如您所指出的,克隆是一种受保护的方法,这意味着只有当您的对象位于java.lang的同一个包中时,它才能访问对象的克隆方法。”表面上看,这听起来是错误的。但让我重新考虑一下……好吧,我想我现在明白了+谢谢你让我思考。对不起,小姐。我想说的是,您的类不能访问Object的clone方法,但它可以作为Object的子类来使用或重写它:它只能通过位于同一个包中来访问对象实现(读取:use Object.clone(),而不是yourclass.clone()),即,从该引用中注意,类可以访问同一个包中任何类的受保护成员。您有一个输入错误:public class Child扩展Base{}{[…]}Hm。虽然您从Javaspec复制的内容听起来很有说服力,但您的代码编译得非常好。这似乎与我的例子有所不同。这是因为包装业务——我修改了文本,说Base必须在不同的包装中。我也会把它写进代码里。啊,当然。否则,访问受保护方法的包方式仍然有效。很难相信当我查看
Clonable
Object.clone()
时,我会有完全相同的困惑-谢谢。
package first;
public class Base
{
    protected void Foo() {}
}

// Yes, each class is really in its own file normally - but treat
// all the classes below as being in package "second"

package second;
public class Child extends Base
{
    public void OtherMethod(Object x)
    {
        ((Base) x).Foo(); // Invalid: Base is not Child or subclass
        ((Child) x).Foo(); // Valid: Child is Child
        ((GrandChild) x).Foo(); // Valid: GrandChild is subclass of Child
        ((OtherChild) x).Foo(); // Invalid: OtherChild is not Child or subclass
    }
}

public class GrandChild extends Child {}
public class OtherChild extends Base {}