为什么Java缺少访问权限说明符?

有谁知道为什么缺少Java:

  • 一个访问说明符,允许类和所有子类访问,但不允许同一个包中的其他类访问? (保护-负)
  • 一个访问说明符,允许类访问,同一个包中的所有类,以及任何子包中的所有类? (默认加)
  • 一个访问说明符,它将子包中的类添加到当前允许受保护访问的实体中? (被保护的加)

我希望我有更多选择而不是保护和默认。 特别是,我对Protected-plus选项很感兴趣。

假设我想使用Builder / Factory图案类来生成一个具有许多指向其他对象的链接的对象。 对象上的构造函数都是默认的,因为我想强制您使用工厂类来生成实例,以确保正确完成链接。 我想将工厂分组在一个子包中,以便将它们保持在一起并与它们实例化的对象区别开来 – 这对我来说似乎是一个更清洁的包结构。

目前无法做到。 我必须将构建器放在与它们构造的对象相同的包中,以获得对默认值的访问。 但是将project.area.objectsproject.area.objects.builders分开会非常好。

那么为什么Java缺乏这些选择呢? 并且,无论如何要伪造它?

一次一个地回答您的问题:

 * An access specifier which allows access by the class and all subclasses, but NOT by other classes in the same package? (Protected-minus) 

这是在Java 1.0( private protected是修改器 )并删除。 我不清楚为什么,但它肯定被视为不值得麻烦的东西。 当前的安排使得所有修饰符从较少限制变为更受限制,这更简单(如在较小的潜在变化中),这是Java设计目标。

 * An access specifier which allows access by the class, all classes in the same package, AND all classes in any sub-package? (Default-plus) * An access specifier which adds classes in sub-packages to the entities currently allowed access by protected? (Protected-plus) 

这两个因相关原因无法使用。 Java目前没有子包的概念,它只是假装常规文件和基于jar的类加载器(以及编译器)遵循底层文件系统的目录结构来查找文件。 Java将使用JSR 294(“超级包”)更广泛地解决这个问题(正如其他人所指出的那样),这将使您对包外发布的内容进行更细粒度的控制(因此,如果您愿意,可以公开内容)到,它仍然不可见)。

有谁知道为什么缺少Java:

  • 一个访问说明符,允许类访问,同一个包中的所有类,以及任何子包中的所有类? (默认加)
  • 一个访问说明符,它将子包中的类添加到当前允许受保护访问的实体中? (被保护的加)

Java的包不是分层的 – 没有子包(即使目录结构表明它)。 “内部”其他包的包不是真正的子包,它们只是名称恰好以“父”包的相同前缀开头的包。 导入包时也可以看到这个; 像这样的陈述

 import java.awt.*; 

只导入包java.awt中的所有内容,而不是java.awt.image所有内容。

因此,也没有适用于子包的访问说明符。

查看将在Java 7中出现的超级软件包function:

  • 开放之路:超级包装
  • 改进了Java 7中的模块化

据推测,要保持简单。

虽然我们讨论的是:我错过了一个访问说明符,它允许仅使用this指针(对象级而不是类级封装)修改字段。 能够为读取和写入字段指定不同的访问修饰符会很好。

编辑 :Java语言设计中的一个特定目标是使用简单的语言 ,特别是与C ++相比。 当然,这需要付出代价; Java中的一些事情比C ++更难做,因为编译器提供的支持较少。 考虑遗漏const 。 安全地将只读引用暴露给内部状态非常麻烦。 但是,它还可以防止初学者被与const正确性相关的众多编译器错误所混淆。

我认为你的问题的一部分在这句话中:

对象上的构造函数都是默认的,因为我想强制您使用工厂类来生成实例,以确保正确完成链接

您是否真的需要强制您的代码用户只能使用某些方法/构造函数?

您是否可以简单地记录“为了让这个类正常工作,所有实例必须通过使用这个工厂来构建?” 并相信他们会遵循你给他们的文件?

任何偏离您的文档的人都是冒着自己的风险和危险。