优点和包私有类的缺点在Java中?

问题描述 投票:60回答:8

我学习Java最近,我整个package-private类的概念,这是如果我们不指定任何默认的就来了。但后来我意识到:

  1. 我很少看到使用包私有类的。是否有一个原因,例如,它有严重的缺点,它是多余的,或者干脆我不读书还不够吗?对于有强烈的反对意见赞成/反对它的使用?
  2. 如果真的是没有用在大多数情况下,它为什么会是默认?
  3. 在什么情况下,我们应该用包私人在现实世界?即,它的时候会成为不可替代的?

换句话说,什么是默认的包,专用改性剂的主要优点和缺点?

java class default modifier package-private
8个回答
52
投票

答案很简单 - 它是私人稍宽形式。

我假设你熟悉publicprivate之间的区别,以及为什么它通常是很好的做法,使方法和变量private如果他们要单独用于内部问题的类。

那么,作为一个扩展, - 如果你想在一个模块化的方式建立你的软件,你可能会想到一个公共接口的模块,这将有多个类里面彼此之间的合作。在这方面,非常有意义,使方法public如果他们要被消费者称为; private如果他们内部的类的;和package private如果他们使用这个模块中的类之间的调用,即它是你模块的实现细节(公共呼叫者可以看到),但跨越几类。

这是很少在实践中使用,因为包系统最终未能对这样的事情非常有用。你不得不抛售所有类的一个给定模块到一模一样的包,这对于任何不平凡的是会得到一个有点笨拙。这样的想法是伟大的 - 让一个方法访问只是一个“附近的”一小撮阶级作为一个稍宽private - 但你如何定义组类的限制意味着它很少使用/有用。


14
投票

有关包和私营部门的一个好处是,你可以用它来给访问方法,否则你会考虑以私人单元测试类。当然,缺点在于其他类的包可以当他们真的不应该调用它。


4
投票

除了封装,采用包私有类的主要优点之一是,它们不会出现在你的项目中的Javadoc。所以,如果你使用的没有其他用途,但帮助你的公共类做一些客户需要一些辅助类,它是有道理的,使你希望保持尽可能简单的库的用户他们包专用。

举个例子,你可以看看,我已经开发了一个图书馆。该javadoc只包含5个接口和12个班虽然source code有很多。但是,什么是隐藏的是大部分是用于客户端(通常所有的抽象基类被隐藏)提供无附加值的内部层。

也有在JDK例子很多。


2
投票

关于这个问题:“为什么它是默认的,”在此背景下,术语“默认”只是意味着没有其他修饰词。我猜他们能够发明另一个关键字(“包”已经采取了),但他们没有。

在现实世界中,我使用的工具类和抽象类的默认访问,我不想让别人打电话或以其他方式从其他包使用。比方说,你有一个接口和一些抽象类扩展两个具体的实现。你申报你的两个具体类为final,因为你不一定要人们继承他们(见有效的Java)。你也不想让人猴子身边与你出于同样的原因抽象类。如果您使用抽象类的默认访问,那么人们只看到它,如果他们把自己的阶级在你的包。这不是防弹的,但我认为这是默认的访问合理利用/插图。这就是说,一个事实,即它不会阻止泄漏私人会,即不能保证任何事情的细节,意味着它不是一个特别有用的约定。

另一个原因,你没有看到它应用较多的是,人们往往排除与他们的javadoc默认访问类。


2
投票

封装和私营部门的访问级别有更多的限制比protected:受保护的属性和方法,仍然可以通过简单地继承一个类来访问。受保护的成员是(或可以被)旨在用于继承而包私有成员则没有。

包私有成员经常使用这样的多个类的包内可以访问特定于实现的属性或(实用)的方法。

这个最好的例子就是StringStringBuilder.value字符数组的包私有构造函数:

/*
* Package private constructor which shares value array for speed.
* this constructor is always expected to be called with share==true.
* a separate constructor is needed because we already have a public
* String(char[]) constructor that makes a copy of the given char[].
*/
String(char[] value, boolean share) {
    // assert share : "unshared not supported";
    this.value = value;
}

所以java.lang包中的类可以高效地创建新Strings如果内容已经存在于char[]不会影响安全性。你不能从你的应用程序做到这一点,因为如果可以的话,你将有机会获得(参考)到String这是不可改变的内部字符数组(反射不计!)。

StringBuilder(或更确切地说AbstractStringBuilder其中执行来自)char数组保持的电流值char[] value和存取方法本char[] getValue()也像String contentEquals(StringBuffer sb)的包私人所以各种实用程序的方法和contentEquals(CharSequence cs)可以利用该对效率和更快的比较不露出内部字符数组的“世界”。


1
投票

1 - 对建筑-Generally如果你只是你自己和你可能不会使用它的小项目编写代码依赖。在较大的项目也可以是有帮助的,以确保您可以控制方法是在哪里以及如何一定的调用。

2 - 默认(即没有公共/保护/私有的)是不一样的私人 - 它的第4个状态。见Java Access Control

3 - 它可以使生活更轻松,当你写,你不希望第三方依靠你是如何实现的底层代码库 - 你只要把API本身市民。


0
投票

请注意,当你在谈论类你只有两个选择:

  1. 公开课
  2. 包专用类

“私有类”的概念是没有意义的。 (为什么做未在任何地方使用的一类?!)

所以,如果你有需要不被暴露于API用户中间操作的类,你应该将其声明为“包专用”

此外,当你定义相同的源文件中的许多类,只有一个类被允许是公共的(它的名字相匹配的java文件名)。如果任何其他类在同一个文件中定义它必须是“包专用”。


-1
投票

它的使用,当你有几个包,这意味着,在同一个包中的其他类可以访问类或类成员为“公共”,“包私人”,班中其他的包无法访问,它像“私人喜欢他们。”

© www.soinside.com 2019 - 2024. All rights reserved.