最近,我正在编写一个类,我决定将其作为包私有(即,没有访问修饰符,或者默认一个)。它有一个内部类和一些private
辅助方法,以及一个旨在由同一个包中的类使用的方法。所有这些班级成员都是static
。但后来我有一个想法:这个方法应该有public
访问修饰符还是没有访问修饰符,比如包含它的类?
一方面,由于类本身是包私有的,因此只能在其包中访问和使用它,因此没有实际的理由来创建方法public
。但同时,在语义上,此方法旨在成为类的 public 特性,即,旨在外部使用的类的特性,因此修改它的意义是有意义的。这样访问。
对于那些喜欢看代码的人,
final class DummyRemover {
private DummyRemover() {
}
public static int remove(Map<String, ClassNode> classMap) {
return 0;
}
// ...
}
,或者
final class DummyRemover {
private DummyRemover() {
}
// Notice the modifier.
static int remove(Map<String, ClassNode> classMap) {
return 0;
}
// ...
}
这里最好的选择是什么?是否有一个经验法则来决定在这种情况下使用哪些访问修饰符?
答案 0 :(得分:5)
为什么方法应该具有比其封闭类更高的可见性有两个原因:
...用于子类扩展,最终可能是公共的,并且手头的方法应该是公开可用的。 E.g。
abstract class Base {
public void x() {}
}
public class Sub extends Base {
}
// Now, everyone can call:
new Sub().x();
但是,通常,如果这是您的意图,您仍然会在界面中声明方法x()
。即使您没有在设计方面在接口中声明x()
,最好将基本方法保持在与其类相同的可见性级别,并“打开”子类中的方法,因为将更清楚地传达意图:
abstract class Base {
void x() {}
}
public class Sub extends Base {
/** public Javadoc here */
@Override
public void x() {
super.x();
}
}
我认为没有任何理由可以将此方法应用于静态方法,如您的情况。
...因为它从接口实现了一个方法。遗憾的是,Java不提供包私有或私有接口方法。所以下面是通常的,即使没有任何子类,即使接口本身可能是包私有的(甚至是嵌套的私有):
final class Y implements X {
@Override
public void x() {}
}
这(不幸的是)也适用于接口上的静态类,它们只能是公共的:
interface I {
/* implicitly public */ static void x() {}
}
答案 1 :(得分:3)
这有两种思想流派:
一个群体更喜欢添加不必要的修饰符(例如,在这种情况下为public
,私有类中为private
)作为代码&#34;中的文档形式。例如,这是Eric Lippert在his answer on this related C# question中所支持的观点。
另一组更喜欢永远不会添加没有功能效果的源代码:如果public
不是做任何事情那么它就不属于您的源代码
我想我现在已经坚定地进入了第二阵营,但我理解第一阵营的论点,我认为它并不像它最初出现的那样切割和干燥。合理的人可以不同意,这就是为什么(如大括号和空白)这是你应该在项目风格指南中决定一次然后再也不再辩论的事情。 : - )
答案 2 :(得分:0)
我个人认为制作方法public
可能会误导读者。
另一方面,它支持可扩展性(如果该类应该公开,则更改更容易)。
每当我需要在可读性和可扩展性之间做出选择时,我会选择 YAGNI 原则并选择可读性。
有关YAGNI的更多信息,请参阅维基:https://en.wikipedia.org/wiki/You_aren%27t_gonna_need_it