Java中的私人访问修饰符?

这个问题在这里已经有了答案:

  • 在Java中,封装私有,公共,受保护和私有26个答案之间的区别

  • 第一个答案基本上是正确的 - protected成员可以被访问

  • 来自同一个包的类
  • 来自其他包的声明类的子类
  • 但是,有一个小技巧:

    6.6.2受保护访问的详细信息

    对象的受保护成员或构造函数可以从仅在负责实现该对象的代码声明的包中进行访问。

    这意味着来自其他包的子类不能访问其超类的任意实例的protected成员,它们只能在它们自己类型的实例(其中type是编译时类型的表达式,因为它是编译时检查)中访问它们。

    例如(假设这个代码在Cat ):

    Dog dog = new Dog();
    Animal cat = new Cat();
    
    dog.testInstanceMethod(); // Not allowed, because Cat should not be able to access protected members of Dog
    cat.testInstanceMethod(); // Not allowed, because compiler doesn't know that runtime type of cat is Cat
    
    ((Cat) cat).testInstanceMethod(); // Allowed
    

    这是有道理的,因为访问protected的成员DogCat可能会破坏不变量Dog ,而Cat可以访问它自己的protected安全成员,因为它知道如何保证自己的不变量。

    细则:

    6.6.2.1访问受保护的成员

    设C是声明保护成员m的类。 只有在C的子类S的主体内才允许访问。另外,如果Id表示实例字段或实例方法,则:

  • 如果访问是通过限定名Q.Id访问的,其中Q是一个表达式名,那么当且仅当表达式Q的类型是S或S的一个子类时才允许访问。
  • 如果通过字段访问表达式E.Id(其中E是主表达式)或通过方法调用表达式E.Id(...)(其中E是主表达式)访问,则只有当且仅当如果E的类型是S或S的一个子类
  • 6.6.2.2有资格访问受保护的构造函数

    设C是声明受保护的构造函数的类,并让S为声明中使用受保护的构造函数的最内层类。 然后:

  • 如果访问是通过超类构造函数super(...)或通过形式为E.super(...)的合格超类构造函数调用(其中E是主表达式),则允许访问。
  • 如果访问是通过形式为new C(...){...}的匿名类实例创建表达式或由形式为E.new C(...){...)的合格类实例创建表达式创建的... },其中E是主表达式,则允许访问。
  • 否则,如果访问是通过形式为new C(...)的简单类实例创建表达式或由形式为E.new C(...)的限定类实例创建表达式来实现的,其中E是主表达式,那么访问是不被允许的。 受保护的构造函数只能由定义它的包中的类实例创建表达式(它不会声明匿名类)访问。
  • 也可以看看:

  • Java语言规范

  • 在受保护的访问中,成员可以在同一个包中访问,并且也可以访问另一个包中的继承类成员。

    在包访问中,可以访问同一包中类的成员。 其他包中的类成员不能通过包访问进行访问。


    您已创建一个Cat实例并将其转换为其超类类型,即Animal类型。 按照Animal类型,它的testInstanceMethod在相同的包或任何子类型中都可见。 如果你没有投入动物类型的代码将编译。

    希望有所帮助

    ./Arun

    链接地址: http://www.djcxy.com/p/4119.html

    上一篇: private access modifiers in Java?

    下一篇: Does Python have “private” variables in classes?