包私有类中的公共方法

fre*_*low 42 java methods visibility package public-method

将方法标记为public包私有类是否有所不同?

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

    public void bar();   // public method
}
Run Code Online (Sandbox Code Playgroud)

这之间foobar这里的可见度是否存在实际差异?

Tho*_*mas 42

使用继承的示例:

A.java

package pkg1

class A {
  void foo();
  public void bar() {};
}
Run Code Online (Sandbox Code Playgroud)

B.java

package pkg1

public class B extends A{

}
Run Code Online (Sandbox Code Playgroud)

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
  }
}
Run Code Online (Sandbox Code Playgroud)


Pét*_*rök 20

如果该类不会被另一个更可见的子类*扩展,唯一的区别就是意图的清晰度.将所有方法包声明为私有使得将来的读者更难以确定哪些方法是由同一包中的其他类调用的.

*作为我的设计解决方案没有多大意义,但技术上仍然可行.

  • "声明所有方法私有"应该读作"声明所有方法包私有","封闭类"作为"其他类",我猜,但否则+1 (2认同)

Jör*_*ann 10

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


mid*_*ite 6

嗯......我也有这个疑问(这就是为什么我搜索这个帖子).这可能是个好问题.

但......

经过一番思考,事情真的比我们想象的要简单.

package-private方法是一种package-private方法.

好像胡说八道?但......

一个package-private方法,即使它的类是继承的,它仍然是一个package-private方法.

现在更有意义吗?有关更详细的解释:

一个package-private方法,即使它的类是由一个更可见的子类继承的,它仍然是一个package-private方法.

如果子类是同一个包,那些package-private方法也是继承的,但它们仍然是包私有的.

如果子类是不同的包(在这里,我们需要父类是公共的,使用一些包私有方法),那些包私有方法不会被继承(因为它们根本不可见).

需要注意的一点是,这可能是造成这种疑问的原因,公共类中的包私有方法在其包之外也是不可见的.


以上解释了包私有方法.而公共方法的情况也是一样的.

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

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

希望这很清楚(也很简单).

PS Java访问控制表


blu*_*ote 6

是的。 public包私有类中的方法可能很有用(尽管它们很少见)。来自 java 库的说明性示例(取自经典书籍“ Effective java”):

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

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

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


Tom*_*ine 5

除非该类由公共(或受保护的嵌套)类扩展,否则它几乎没有什么区别.

作为一致的问题,我会去public.方法应该是罕见的除了public或之外的任何东西private.

包私有java.lang.AbstractStringBuilder类中有许多公共方法的示例.例如length(),public AbstractStringBuilder是公共类,并在公共类中公开StringBuilder(重写StringBuffer为添加同步).