![]() |
1
33
根据我的经验,包级可见性有两个很好的用途: 1) 在公共API中定义“内部”类。通常,您会将接口和核心工厂定义为公共,将“内部”实现定义为包级。然后,公共工厂可以构建包级实现类,并将其作为公共接口的实例返回。这很好地允许用户只访问他们应该访问的内容。
缺点是必须将所有这些东西放在同一个包中,这对于任何大小合理的API来说几乎都不是一个好主意。
JSR 294
/模块/
Project Jigsaw
在Java 7中,通过指定一个新的可见性修饰符,有望提供一种替代方案(
2) 单元测试是另一个常见用例。您经常会看到一个src树和一个测试树,否则这些树将是私有的,而不是包级的,这样同一(并行)包中的单元测试就能够访问其他隐藏的方法来检查或操纵状态。 |
![]() |
2
12
你是在谈论Java中的包私有保护吗?这是默认情况下对类成员生效的保护。如果你的类以一种需要额外信息或方法才能可见的方式密切交互,那么它偶尔会很有用。 假设你有一个Sink类,有几个类可以写入该类。Sink有一个接受基本数据类型的公共方法和一个接受原始字节数组的包私有方法。你不想将该方法设为公共,因为你认为它对用户来说太低级了,但你想让写入该接收器的其他类(在接收器的包中)使用它。因此,你将接受字节数组包的方法设为私有,并且包中的类(如ByteStreamSource)可以使用它。现在,你的保护看起来像这样:
包私有接口与公共方法建立的公共接口正交。包私有性增加了封装,因为它鼓励你
不
公开不应该公开的东西。它类似于
|
![]() |
3
8
首先,它可以用于实现类。例如,
在这种情况下,私有内部类可能就足够了(尽管笨拙,尤其是对于大型类)。但有时包中的其他类需要访问这些实现细节。
简而言之,它覆盖了其他三个保护级别无法处理的封装区域。 |
![]() |
4
5
我认为原则上,包级保护很有意义。它允许您创建接近模块(包)的东西,但只公开核心类。 例如,我的许多项目都使用公共接口和实现它们的“隐藏”类。用户使用工厂,并收到对接口的引用,该接口对应于“隐藏”的具体实现。理论上,有了包保护,我应该只能暴露接口和工厂。 不幸的是,因为包保护不适用于子包,所以它并不适合我的工作方式。我喜欢使用其他包,特别是子包来处理我的“内部”内容(与Eclipse的组织方式相同)。因此,我的包无法访问子包中受包级保护的内容。我真希望有一天能改变这一点。 |
![]() |
5
3
默认的protexction,即“包”保护意味着它对包是私有的,但可以“看到”包中类不私有的任何东西。一个用途是用于包的辅助类;假设你有一个管理池资源的类,你不想让它可见,你可以把它放在默认的保护类中。现在,它可以被包中的所有东西使用,并且可以访问其他类的任何受保护的内部,但它不是用户可见包的一部分。 |
![]() |
6
3
Java中默认保护的另一个用途是性能。 允许内部类访问其包含类的私有成员,但这是通过混淆的访问器方法实现的。在JIT编译器优化之前(或在没有JIT的环境中,如J2ME),这会导致性能下降。使用默认保护声明所需的方法消除了对这些访问器方法调用的需要,但不需要使成员完全公开。 请记住,只有在已知性能至关重要的情况下,以及在不能指望JVM为您解决问题的情况下才重要。但至少它不会像许多其他微优化那样真正损害可读性/可维护性。 |
![]() |
7
2
在我看来,方法和字段的包私有(默认)访问是无用的。事实上,它比无用更糟糕,它是有害的,因为它通常用于为一些应该是私有的但不是出于方便的原因的成员提供访问权限。 但是,打包私有类 是 有用的。您可能希望使用包私有类提供接口的实现。可以声明一个工厂方法来返回实现给定接口的对象。在这种情况下,知道哪个类为接口提供实现并不重要。通过使类package-private,它不是公共API的一部分,因此可以在未来的版本中进行修改或替换。 在后来成为Java的Oak语言中, there were only 3 access levels . 如果我现在重新设计Java,我会去掉当前的默认值(包私有),将私有设置为默认值。私有类将是在其封闭范围(包)内私有的类,这将与包私有类的工作方式完全相同 和 与会员使用“private”更为一致。 |
![]() |
8
2
没有人使用包级访问的原因可能是心理影响。每个java介绍都宣扬封装,这被理解为声明所有字段都是私有的。私有访问通常太窄,因此必须添加公共getter/setter。然后,这种模式在整个代码库中重复:到处都是私有字段和公共方法。具有讽刺意味的是,该模式颠覆了封装,因为整个实现基本上是由getter/setter对固定的。 类主要是内存分配的单位,在许多情况下,它太小,无法为程序的其余部分提供有意义的接口。使用包作为封装单元并专注于为它们提供定义良好的公共接口是一个更好的主意。 1.7版本的超级包装可能会改变游戏规则。 |
![]() |
9
1
我有一些需要相互访问的对象。在包内,它们可以调用这些受保护的方法,但当有人试图访问这些受保护方法时,它们将被禁止。 在我看来,这是一种基本的保护机制,保护层次结构将是一个很好的功能。 |
![]() |
10
1
如今,包通常用于对“软件组件”进行建模,即包是一组以某种方式相关的类。由于“公共”方法定义了软件组件的外部接口,而“私有”方法/成员是类的实现细节,因此默认的“包”可见性相当于组件内部方法。 一个类比可能是C++中的“friend”方法。 |
![]() |
11
1
我认识5-10岁以上的Java老手,他们没有意识到这一点
将其与受保护的方法进行比较,在为扩展设计类时,这些方法是完全合理的。我见过程序员的案例 无意地 在同一包中不相关的类中使用受保护的方法,仅仅因为它们出现在自动补全列表中。 而且绝对没有办法阻止这种情况。 C#有一个更好的访问系统,因为受保护并不意味着内部访问。但我认为这——以及一个可变的Date类——是相当大的缺陷。 |
![]() |
12
1
主要用于源文件和测试文件位于同一包中的单元测试,测试可以访问类的内部,而无需公开它。 |
![]() |
13
1
我目前正在脑海中讨论许多这些问题,这是一个很好的讨论。我一直在选择让所有私有的东西都像它们应该的那样私有,但后来我正在编写大量的反射到单元测试私有范围的代码。我认为这是纯面向对象的方法。然而,我发现可以密封一个jar文件,将包作用域限制在模块(jar)内部。在我看来,这使得包装范围更加可口。我可能愿意打破良好的封装,以换取将我的单元测试代码减少到原来的一小部分。我的想法是,如果有人在同一个库和同一个包中工作,他们将与代码库足够亲密,在没有合理的设计辩论的情况下,不会从类外访问包作用域成员。这仍然是一个艰难的决定。为这种类型的实例指定一个朋友类类型会很好,这样我的单元测试代码就可以访问我的私有代码,而不会被其他类访问。我刚刚通过maven将jar文件密封在这个项目中:
现在,我正在讨论在我的单元测试中提取一堆反射代码。 我仍然处于辩论的边缘。包的作用域非常开放,特别是当你有很多开发人员在代码库中来回走动时。 |
![]() |
14
0
一般来说,默认/包保护可用于使“公共”类和变量受到更多限制。 如果你是一名优秀的程序员,你只需将类中的一些方法标记为公共,同时尽可能多地保持私有,就可以从类中导出这些方法。 包保护允许您仅从包中导出少数类,其余类保持私有。 从理论上讲,这是一个好主意,但在实践中,你几乎从未见过它。 |
![]() |
15
0
“我知道java中的包级保护是如何工作的……但似乎没有人使用它。” 他们在用什么? 他们把所有的课都公开了吗? 负担原则有两种形式。 强形式表明,转换实体集合的负担是转换实体数量的函数。弱形式指出,转换实体集合的最大潜在负担是转换实体的最大潜在数量的函数。 国际标准化组织将封装定义为对象中包含的信息只能通过对象支持的接口处的交互访问的属性。 在更高的抽象层次上,程序单元也可以封装在子系统中,因此子系统中包含的信息只能通过子系统中的公共程序单元访问。 创建或修改任何软件系统的负担取决于创建或修改的程序单元的数量。 依赖于特定修改后的程序单元的程序单元比不依赖于修改后程序单元的编程单元更有可能受到影响。 修改后的程序单元可以施加的最大潜在负担是依赖它的所有程序单元的影响。 因此,减少对修改后的程序单元的依赖性可以降低其更新影响其他程序单元的可能性,从而减少该程序单元可能施加的最大潜在负担。 因此,减少系统中所有程序单元之间的最大潜在依赖数量可以降低对特定程序单元的影响导致其他程序单元更新的可能性,从而减少所有更新的最大潜在负担。 封装理论展示了如何使用封装来减少所有程序单元之间的最大潜在依赖数量。 因此,封装理论展示了如何使用封装来减轻负担原则的弱形式。 在Java中,将类包私有化是减少系统中最大潜在依赖关系数量的关键机制之一,从而减少对该系统进行任何软件修改的最大可能负担。 然而,你提到这在你阅读的代码中没有使用。 听起来不错。..奇怪。 |
|
user29759326 · 如何返回递归函数中的最后一个值? 5 月前 |
|
malife89 · 将java中的字符串读取为正确的日期格式 5 月前 |
![]() |
Tim · 在java中,有没有更快的方法将字节数组写入文件? 5 月前 |
![]() |
rudraraj · java中未声明最终变量 5 月前 |
![]() |
Bala Ji · 以下BFS的实施效率如何? 6 月前 |