类具有默认访问权限时的 Java 成员访问权限

Posted

技术标签:

【中文标题】类具有默认访问权限时的 Java 成员访问权限【英文标题】:Java member access when class has default access 【发布时间】:2017-10-08 13:57:28 【问题描述】:

假设我有一个声明为默认访问的类。如果类中的成员声明为protectedpublic,是否等同于声明为default 访问权限的成员?

例如:

在 CarA.java 中:

class CarA  //class declared with default access
   public int odometer;
   protected void forward(int distance)...
   
   protected static void tally()...
   

在 CarB.java 中:

class CarB  //class declared with default access
   int odometer;
   void forward(int distance)...
   
   static void tally()...
   

CarACarB 是否等效?

我的理由是,由于该类未声明为public,因此该类在其包外不可访问,因此其成员也不应在其包外访问。有人可以确认我的想法是正确的吗?

【问题讨论】:

看这个,***.com/questions/215497/… 我相信你需要read this QA。它在方法可见性和类可见性方面没有什么不同.. afaik. 这些资源似乎分别解决了类和成员的访问权限,但不是我上面指出的组合。 @BagusTesa 如果类具有默认(包私有)访问权限,您将如何从包外部访问公共成员? 【参考方案1】:

不,它们不相等。在同一个包中定义这些:

public class CarC extends CarA  

public class CarD extends CarB  

在不同的包装中:

import your.package.CarC;
import your.package.CarD;
public class NewClass

    public static void tryThis(CarC c, CarD d) 
        int n1 = c.odometer;  // legal
        int n2 = d.odometer;  // illegal
    

【讨论】:

这很可怕。【参考方案2】:

不,这些是不等价的。里程表几乎具有同等特权*,但方法不会。

这是因为您所说的“默认访问”,也称为包私有,意味着该包的其他成员可以访问相关对象或方法。因此,在您将里程表公开的地方,它基本上可用于任何可以访问父类的东西,方法的受保护状态将可用于扩展相关类的包和类,即使它们不在包,不像包私有。

*CarA 中的公共里程表可以通过此包外部的对象或方法访问,方法是通过扩展此类的公共类路由它,而 CarB 中的包私有里程表始终是包私有的。这就是为什么人们应该避免编写这样的代码的一个重要原因,其他开发人员可能会认为该变量不是公开可用的。

【讨论】:

odometer 也不完全等同——请参阅我的回答。 好收获。我没想到偷偷溜进公共课。 Glen Pierce,您说“方法的受保护状态仅适用于扩展相关类的类,而不适用于包内的任何内容”。如果我理解正确,protected 成员在同一个包内的任何地方都可见,包括非子类。 @flow2k 你是对的,我已经编辑了我的答案。谢谢:)【参考方案3】:

据我所知,当您可以创建类的实例或继承该类时,您可以访问该类的成员。

无法在包外访问默认类。所以我认为你也不能继承它(在包之外)。所以我认为它们几乎相同。

当您可以访问类本身(CarA)时,您可以访问该类的受保护成员。

希望我是对的,这会给你一些想法。

【讨论】:

看来我做错了 - ajb 上面有一个聪明的反例。

以上是关于类具有默认访问权限时的 Java 成员访问权限的主要内容,如果未能解决你的问题,请参考以下文章

Java中成员属性默认访问修饰符是啥

java类中的成员缺省(默认的)的修饰符是啥??

Java访问权限控制中,友好变量或方法能在类内部、本包中使用,不能在子类及包外使用,但请看下面代码:

java中public和缺省这两个访问权限的根本区别,举例子

Java之路 访问权限控制

什么是Java类的访问权限?