Java 包私有类中的公共方法

Java 包私有类中的公共方法,java,methods,package,visibility,public-method,Java,Methods,Package,Visibility,Public Method,在包私有类中将方法标记为public,会有区别吗 class SomePackagePrivateClass { void foo(); // package private method public void bar(); // public method } 这里的foo和bar之间在可见性方面有什么实际区别吗?除非该类由公共(或受保护的嵌套)类扩展,否则差别很小 为了保持一致性,我选择了public。除了public或private之外,很少有其

在包私有类中将方法标记为
public
,会有区别吗

class SomePackagePrivateClass
{
    void foo();          // package private method

    public void bar();   // public method
}

这里的
foo
bar
之间在可见性方面有什么实际区别吗?

除非该类由公共(或受保护的嵌套)类扩展,否则差别很小

为了保持一致性,我选择了
public
。除了
public
private
之外,很少有其他方法


包private
java.lang.AbstractStringBuilder
类中有许多公共方法的示例。例如,
length()
AbstractStringBuilder
中是公共的,并在公共类
StringBuilder
中公开(在
StringBuffer
中重写以添加同步)。将包中的所有方法声明为私有会使未来的读者更难确定哪些方法将由同一包中的其他类调用


*这对于我来说,作为设计解决方案没有多大意义,但在技术上是可行的。

使用继承的示例:

A.java

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
  }
}

方法必须是公共的另一种情况是,当您创建某个公共类或接口的包私有实现时。由于不允许降低重写方法的可见性,因此这些方法必须是公共的。

嗯。。。我也有这个疑问(这就是为什么我搜索这个线程)。这可能是个好问题

但是

再想一想,事情真的比我们想象的要简单

包私有方法,是包私有方法

似乎是胡说八道?但是

一个包私有方法,即使它的类被继承,它仍然是一个包私有方法

现在它更有意义了吗?如需更详细的解释:

一个包私有方法,即使它的类被一个更可见的子类继承,它仍然是一个包私有方法

如果子类属于同一个包,那么这些包私有方法也会被继承,但它们仍然是包私有的

如果子类属于不同的包(当然,我们需要父类是公共的,带有一些包私有方法),那么这些包私有方法是继承的(因为它们根本不可见)

需要注意的一点是,公共类中的包私有方法在其包外部也不可见,这可能是产生此疑问的原因


上面解释了包私有方法。公共方法的情况也一样

当一个包私有类被一个公共子类(属于同一个包,这是必须的)继承时,它的公共方法被继承为公共方法,因此它们成为公共类中的公共方法

在OP示例中,由于
foo()
bar()
都在包私有类中,因此此时它们的可视性仅限于包私有,直到添加更多代码(例如继承)

希望这足够清楚(简单)


注意:是的<包私有类中的code>public方法可能很有用(尽管它们很少)。java库中的示例(摘自经典书籍“有效java”):

你见过
java.util.JumboEnumSet,java.util.RegularEnumSet
??可能不会,因为它们是私有的,文档中没有提到

你用过吗??可能是的。它们由
java.util.EnumSet.noneOf(…)
的静态方法返回。虽然您不能自己构造它们,但是当它们从这个方法返回时,您可以使用它们的公共方法


好的是你不知道你在用哪一个,甚至不知道它们的存在。Java根据参数决定哪一个更有效,并可能在新版本中使用不同的on。只有通过它们的公共接口引用它们才能访问它们的功能(无论如何,这是一个很好的实践!!)

一个很好的利用是,当您想将类限制在包中,但仍然想使用代理生成的内容时,例如下面的a方法正上方的
@Transactional

@Service
class SomeService {

   @Transactional
   public void someTxStuff() {
     /// very complicated code here
   }
}


如果
someTxStuff
是包私有的,
@Transactional
注释不会有任何效果。

但是
bar
实际上不具有公共可见性,因为它位于具有默认访问权的类(“包私有”)中.
public void bar
此处使用的修饰符是公共的,因此我猜它具有公共可见性。如果我错了,请纠正我
public void bar()
具有公共可见性,但正如Tom所说,实际上您没有对类的公共访问权限,因此没有对方法的真正公共访问权限(因为您甚至看不到该类)。但是,当涉及到继承时,情况就不同了,正如Tom在回答中指出的那样。@Thomas,如果你能给我一个工作代码示例,我将非常感谢你。我现在很困惑。扩展私有类有意义吗。?扩展包私有类有意义,例如,当类提供由包中的不同实现共享的一些内部基础时(有一些开源项目正在这样做)。
AbstractStringBuilder
(?)由
StringBuffer
StringBuilder
扩展(它在API文档中,但这可能是JavaDoc中的一个bug/misfeature)“声明所有方法为私有”应