在Java中,具有"受保护"修饰符的成员不仅可以由同一个类和子类访问,还可以由同一个包中的每个人访问?
我想知道语言设计的原因,而不是实际的应用程序(例如,测试)
+1坦率地说我也想知道为什么。 它总是让我感到震惊,因为它是Java中最愚蠢的设计决策之一。
@cletus:我想的时间越长,我就得出结论"包私"是一个没有深思熟虑的想法。 对于"封装私有"到实际工作并提供任何类型的实际保护,需要在单个编译单元内编译包。 人们不应该在以后加强它们。
修饰符在http://java.sun.com/docs/books/tutorial/java/javaOO/accesscontrol.html中有详细描述。从那里我们看到这个数字。
Modifier Class Package Subclass World
public Y Y Y Y
protected Y Y Y N
no modifier Y Y N N
private Y N N N
由此可见设计决策的原因很明显:它有一个很好的对称矩阵。
无论如何它会是对称的......
谢谢你这张桌子。
@迈克尔·迈尔斯:嗯,不,不管怎样它都不会对称。它的对称性是有原因的。
如果在protected - >包交叉处放置N而不是Y,则它仍然是对称的。只是不那么漂亮。
@MichaelMyers:我不认为Matrix是对称的。但目前的情况是:所有Y在对角线之上(和之上)以及所有N在下方。
这种设计基于这样的想法:包装是适当的单元,由一个内部一致的团队维护和发布;继承关系与谁维护和释放什么时候关系不大。
感谢您的回答。当然实际上并没有起作用,因为没有人阻止你在几个罐子上分发一个包装 - 并且在几个团队中使用它。所以这是另一个没有充分考虑的好主意。 Java充满了一些东西。
在Java 1.0中,有第五个访问修饰符:private protected。这是protected没有默认访问权限。显然它从来没有真正正常工作,并在1.1中被删除。因此看起来声称protected被定义为总排序的方式似乎是虚假的。 (编辑:看来,在1.1中删除第五个访问修饰符的原因中至少有一个原因是缺少总排序干扰了重载选择规则。)Java 7中的module访问修饰符有一些设计问题在这方面。
鉴于认为成员的默认访问修饰符为"包私有"是个好主意,protected应该至少具有这种访问级别似乎是合理的。对于我的钱,protected根本不会用语言付费。
我从来没有听说过那个,但我在1.1中进入Java ...谢谢!
并且由于没有人阻止您在不同的jar文件中向包中添加更多类,因此"package private"也不是那么私有。原样:除了私人和公共之外的任何东西或多或少都是对程序员的暗示,但没有真正的保护。
一个非常晚的问题,但你有一个来源吗?我现在想更详细地了解当时失败的原因和原因。
@PieterDeBie那是来自记忆。 22年前,我将我正在进行的内部项目从1.0升级到1.1。 bugs.sun.com只给我"私有保护"被删除以简化规范的其他部分 - 例如,有关覆盖的规则要求访问保护是可比较的(即严格地比较弱或强。)
@Martin你可以在清单中将罐子标记为"密封",这可以防止任何添加。当然可以修改jar本身 - 包括类文件。除非您对jar进行签名,否则您无法将任何类添加到具有不同签名的相同运行时包中(假设签名已经过验证)。此外,来自不同类加载器的任何类都将位于不同的运行时包中。
基本上它与包作为api控制单元的视图有关(因此建议使用您的域名启动您的包 - 保证全局唯一性),因此可见性从私有 - > package-private - > protected - > public 。如果受保护不是增加包私有,而是增加不同类型的可见性,则必须有某种方法在需要时组合两种类型的可见性。
但是没有人阻止你在已经退出的包中添加新类。因此,"私有包"和"受保护"只是对程序员的推荐。两者都没有为想要/需要调用该方法的恶意/绝望程序员提供任何真正的保护。 - 像C ++中的"protected"至少会强制使用子类 - 但在Java中你甚至不需要这样做。
鉴于渐进级别的访问,私有,包,受保护和公共,如果它受到保护然后打包将会不必要地限制,因为这将迫使我允许子类访问以便授予同一包的其他成员。然而,直观地说,应该是同一个包中的其他类比"那里"的其他类更值得信赖。所以在包和公共之间受到保护,因为它允许更广泛的访问。
我认为基本原因依赖于直觉,即同一个包中的类之间存在基本的"信任"级别;你可以合理地期望他们彼此做正确的事 - 在大多数情况下,包将由一个工程师或团队负责,所以应该有一致的设计和谐。
这就是理论。但是在实践中,只有当一个包需要在一个编译单元中编译而无法在外部增强时才会出现这种情况。但情况并非如此,因此,在一个苗条的代表类的帮助下,任何"包私有"方法都可以公之于众。对程序员的暗示,但不是真正的保护。
@martin:只有在没有密封的情况下发布包,才能解决这个特殊问题。
"密封包装" - 从来没有听说过,但听起来很有趣。告诉我更多! (几句话帮我google细节就够了)
我自己找到了:docs.oracle.com/javase/tutorial/deployment/jar/sealman.html - 非常有趣。应该默认;-)。
Java确实遵循其设计原则。当您尝试减少/缩小子类中公共方法的范围时会发生什么?一个人得到一个错误。
Java范围修饰符级别如下:private
包中的所有类都应该是友好的,因为它们一起工作。要使成员在包中可用,它将在默认范围内定义。
子类可以驻留在包外部,再次遵循范围级别:private
请不要将修饰符限制为仅可见性,但继承,结构也同时工作并将它们添加到图片中。如果是这样的话:private