public
将方法标记为包私有类中是否有区别?
class SomePackagePrivateClass
{
void foo(); // package private method
public void bar(); // public method
}
foo
和这里的能见度有什么实际区别bar
吗?
public
将方法标记为包私有类中是否有区别?
class SomePackagePrivateClass
{
void foo(); // package private method
public void bar(); // public method
}
foo
和这里的能见度有什么实际区别bar
吗?
使用继承的示例:
爪哇
package pkg1
class A {
void foo();
public void bar() {};
}
B.java
package pkg1
public class B extends A{
}
C.java
package pkg2
public class C {
public void doSomething() {
B b = new B();
b.bar(); //ok
b.foo(); //won't work, since foo() is not visible outside of package 'pkg1'
A a = new A(); //won't work since A is not visible outside of package 'pkg1'
a.bar(); //won't work, since a cannot be created
}
}
如果该类不会被另一个更可见的子类*扩展,唯一的区别是意图的清晰性。将所有方法声明为包私有会使未来的读者更难确定哪些方法应该由同一包中的其他类调用。
*这对我来说作为一种设计解决方案没有多大意义,但在技术上仍然是可能的。
方法必须是公共的另一种情况是当您创建某个公共类或接口的包私有实现时。由于不允许您降低覆盖方法的可见性,因此这些方法必须是公开的。
除非该类由公共(或受保护的嵌套)类扩展,否则几乎没有什么区别。
作为一致性问题,我会选择public
. 方法应该很少是除public
or之外的任何东西private
。
java.lang.AbstractStringBuilder
包私有类中有许多公共方法的示例。例如,在公共类中length()
公开AbstractStringBuilder
并在公共类中公开StringBuilder
(被覆盖StringBuffer
以添加同步)。
嗯......我也有这个疑问(这就是我搜索这个线程的原因)。这可能是个好问题。
但 ...
转念一想,事情真的比我们想象的要简单。
包私有方法,是包私有方法。
好像是废话?但 ...
一个包私有方法,即使它的类被继承,它仍然是一个包私有方法。
现在更有意义了吗?更详细的解释:
一个包私有方法,即使它的类被更可见的子类继承,它仍然是一个包私有方法。
如果子类属于同一个包,那些包私有的方法也会被继承,但它们仍然是包私有的。
如果子类属于不同的包(在这里,我们需要父类是公共的,有一些包私有的方法),那些包私有的方法不会被继承(因为它们根本不可见)。
需要注意的一点,这可能是造成这种疑问的原因,公共类中的包私有方法在其包之外也是不可见的。
上面解释了 package-private 方法。public-method 的情况也是如此。
当一个包私有类被公共子类(同一个包,这是必须的)继承时,它的公共方法作为公共方法被继承,因此它们成为公共类中的公共方法。
在 OP 示例中,由于foo()
和bar()
都在包私有类中,它们的可见性目前仅限于包私有,直到添加更多代码(例如继承)。
希望这足够清楚(和简单)。
PS Java访问控制表
是的。public
包私有类中的方法可能很有用(尽管它们很少见)。来自 java 库的说明性示例(取自经典书籍“有效的 java”):
你见过java.util.JumboEnumSet, java.util.RegularEnumSet
吗??可能不是,因为它们是私有的,并且在文档中没有提到。
你用过它们吗??可能是。它们由 的静态方法返回java.util.EnumSet.noneOf(...)
。虽然你不能自己构造它们,但是当它们从这个方法返回时,你可以使用它们的公共方法。
这样做的好处是你不知道你正在使用哪一个,甚至不知道它们的存在。Java 根据参数决定哪个更有效,并且可能在较新的版本中使用不同的 on。您只能通过它们的通用界面引用它们来访问它们的功能(无论如何这是一个好习惯!!)
一个很好的用途是当你想将你的类限制在你的包中,但仍然想使用代理生成的东西,比如@Transactional
右上方的方法。
@Service
class SomeService {
@Transactional
public void someTxStuff() {
/// very complicated code here
}
}
如果someTxStuff
是包私有的,@Transactional
注释不会有任何效果。
foo
有能见度default package visibility
_ bar
_public