当前位置:  开发笔记 > 编程语言 > 正文

如何保护java.lang.Object的受保护方法不受子类的影响?

如何解决《如何保护java.lang.Object的受保护方法不受子类的影响?》经验,为你挑选了2个好方法。

该关键字protected授予对同一包和子类中的类的访问权限(http://java.sun.com/docs/books/tutorial/java/javaOO/accesscontrol.html).

现在,每个类都有java.lang.Object超类(http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Object.html).

因此,我得出结论,每个班级都可以访问其java.lang.Object方法,即使它们是protected.

看一下下面的例子:

public class Testclass {
  public Object getOne() throws CloneNotSupportedException {
    return this.clone();
  }
  public Object getTwo() throws CloneNotSupportedException {
    return ((Object) this).clone();
  }
}

虽然getOne()编译很好,但getTwo()给出了

Testclass.java:6: clone() has protected access in java.lang.Object
        return ((Object) this).clone();

我既不明白为什么getTwo()不编译也不知道有什么区别(关于java.lang.Objects成员的访问)getOne().



1> Jon Skeet..:

如果您引用它的表达式的编译时类型是您自己的类或子类,则只能访问其他包中的类型的受保护成员.(其中"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 {}

换句话说,它允许您访问"像您一样的对象"的受保护成员.

详细信息在Java语言规范的6.6.2节中:

protected对象的成员或构造可以从它仅由代码中声明的封装,它负责该对象的执行外部访问.

6.6.2.1访问受保护的成员

C是声明受保护成员m的类.访问仅在一个子类的主体允许小号Ç.此外,如果Id表示实例字段或实例方法,则:如果访问是通过限定名称Q.Id,其中QExpressionName,则当且仅当表达式Q的类型为S时才允许访问或S的子类 .如果访问是通过字段访问表达式E.Id,其中E主要的 表达,或通过一个方法调用表达式(.)E.Id,其中Ë是一个 主要表达,则接入是允许的,当且仅当的类型ë小号或的一个子类小号.


请注意,该类可以在同一个包中访问_any_类的受保护成员.

2> MetroidFan20..:

当你说" ((Object) this).clone()"时,你通过它的超类Object访问你自己的对象.您执行了对象的扩展转换.然后代码尝试在Object上调用clone.

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

当你说this.clone时,你的类扩展了Object,因此可以通过受保护的类修饰符直接覆盖或使用克隆,因为继承.但这不会改变Object的实现.

通过说((Object)yourObject),你得到的东西只能通过Object类访问.只有java类的公共方法可以在java.lang包中找到,所以你得到了编译时异常,因为编译器知道这一点.

通过说this.clone(),你正在调用你通过Object继承的对象的clone方法,现在可以调用它,因为它成为你的自定义子类的一部分.

推荐阅读
mobiledu2402851377
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有