web-dev-qa-db-ja.com

パッケージプライベートクラスのパブリックメソッド

パッケージプライベートクラスでメソッドをpublicとしてマークすることは違いますか?

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

    public void bar();   // public method
}

ここでfoobarの可視性に実際的な違いはありますか?

42
fredoverflow

クラスが別のより目に見えるサブクラス*によって拡張されない場合、唯一の違いは意図の明確さです。すべてのメソッドパッケージをprivateと宣言すると、将来の読者が、同じパッケージ内の他のクラスから呼び出されるメソッドを判別することが難しくなります。

*これは、設計ソリューションとしてはあまり意味がありませんが、技術的には可能です。

20
Péter Török

継承の使用例:

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

メソッドある必要がある publicのもう1つのケースは、いくつかのパブリッククラスまたはインターフェイスのパッケージプライベート実装を作成している場合です。オーバーライドされたメソッドの可視性を減らすことは許可されていないため、これらは公開する必要があります。

10
Jörn Horstmann

ええと...私もこの疑問を持っていました(そのため、このスレッドを検索しました)。これは良い質問かもしれません。

だが ...

もう一度考えた後、物事は私たちが思ったよりも本当に簡単です。

Package-privateメソッドは、package-privateメソッドです。

ナンセンスだと思いますか?だが ...

Package-privateメソッドは、そのクラスが継承されている場合でも、stillpackage-privateメソッドです。

今ではもっと意味がありますか?より詳細な説明:

Package-privateメソッドは、そのクラスがより見やすいサブクラスによって継承されている場合でも、stillpackage-privateメソッドです。

サブクラスが同じパッケージの場合、それらのpackage-privateメソッドも継承されますが、それらはまだpackage-privateです。

サブクラスが別のパッケージのものである場合(ここでは、親クラスをパブリックにする必要があり、一部のパッケージプライベートメソッドを使用します)、それらのパッケージプライベートメソッドはではありません継承された(まったく表示されないため)。

この疑いの原因である可能性がある注意点、パブリッククラスのパッケージプライベートメソッドが表示されないそのパッケージの外にも。


上記はpackage-privateメソッドについて説明しています。そして、パブリックメソッドの場合もまったく同じです。

パッケージプライベートクラスが(同じパッケージのpubicサブクラスによって継承されている場合、これは必須です)、そのパブリックメソッドはパブリックメソッドとして継承されるため、パブリッククラスのパブリックメソッドになります。

OPの例では、foo()bar()はどちらもpackage-privateクラスにあるため、コードが追加されるまで(たとえば、継承)、それらの可視性はpackage-privateに制限されます。 )。

これが十分に明確(かつシンプル)であることを願っています。

追伸 the Javaアクセス制御テーブル

6
midnite

クラスがパブリック(またはネストされた保護された)クラスによって拡張されない限り、ほとんど違いはありません。

一貫性の問題として、私はpublicを選びます。メソッドがpublicまたはprivate以外であることはまれです。

パッケージprivate _Java.lang.AbstractStringBuilder_クラスには、パブリックメソッドの例がいくつかあります。たとえば、length()AbstractStringBuilderでパブリックであり、パブリッククラスStringBuilderで公開されています(同期を追加するためにStringBufferでオーバーライドされます)。

はい。パッケージプライベートクラスのpublicメソッドが役立つ場合があります(まれです)。 Javaライブラリからの説明的な例(および古典的な本「効果的なJava」からの引用):

_Java.util.JumboEnumSet, Java.util.RegularEnumSet_を見たことがありますか??それらはプライベートであり、ドキュメントに記載されていないため、おそらくそうではありません。

あなたはそれらを使用したことがありますか?多分そう。これらは、Java.util.EnumSet.noneOf(...)の静的メソッドによって返されます。自分で作成することはできませんが、このメソッドから返されたときにパブリックメソッドを使用できます。

それについての良いことは、あなたがあなたがあなたがどれを使っているか、あるいはそれらが存在することさえ知らないということです。 Javaは、引数に応じてどちらがより効率的かを決定し、新しいバージョンでは別のものを使用する可能性があります。共通のインターフェースを介してそれらを参照することによってのみ機能にアクセスします(これは適切です)とにかく練習!!)

4
blue_note