プライベート静的メソッドがあるのはなぜですか?


68

質問を解決したかっただけです。プライベートな可視性を持つ通常のメソッドとは対照的に、プライベートな静的メソッドを持つことのポイントは何ですか?

静的メソッドを持つことの利点は、クラスのインスタンスなしで呼び出すことができることだと思っていましたが、そのプライベートは静的であるというポイントさえありますか?

私が考えることができる唯一の理由は、オブジェクトレベルではなく、クラスレベルでメソッドを概念的に理解するのに役立つということです。


32
はい、理由があります。パブリック/デフォルトの静的メソッドは、引き続きプライベート静的を呼び出すことができます。静的メソッドを使用する必要があるかどうか、および任意の種類のプライベートメソッドを使用することが適切な場合は別の質問なので、この質問と混同しないように注意してください。

2
簡単な例-他のクラスによる呼び出しを防ぐ内部クラスによって使用されるファクトリーメソッド(ファクトリーメソッドを実行してクラスのインスタンスを取得する必要があります)。

2
@MattFenwick:これを回答として投稿してください。
Doc Brown

9
メソッドを静的にすることで、インスタンス変数の読み取りまたは書き込みを行わないことも意味します。インスタンス変数と相互作用しないメソッドは、他の場所への移動やリファクタリングが簡単になることがよくあります。
マークロジャース14

1
静的メソッドがプライベート、内部、パブリックのいずれであるかに関係なく、特定のコード同期作業なしではスレッドセーフではないことを忘れないでください。
クレイグ14

回答:


70

静的であるという特性は、可視性とは無関係です。

静的メソッド(非静的メンバーに依存しない一部のコード)が必要になる理由は依然として有用です。しかし、多分あなたは誰か/他の人にそれを使わせたくない、あなたのクラスだけを。


3
あなたは正しい軌道に乗っていると思いますが、重要な点を見逃していると思います。ほとんどの静的メソッドには副作用がありません(メソッドではなく、効果的に機能します)。そのため、そもそも静的メソッドになります。それらがプライベートであることに反対する議論は、「副作用がない場合は、コードを再利用するために公開するのはなぜか」です。それが重要なポイントです:プライベートにするとき、それは通常、そのメソッドだけでなく、そのプライベートメソッドを使用するクラス全体再利用したいからです。
corsiKa 14

私はそれをやったことがないか、その行動を見たことがないと言わなければなりません。何度か行ったのは、パブリックスタティッククラスのヘルパーメソッドでした。
宮本明14

1
@corsiKa:副作用は問題ではありません。クラスの静的メンバーを非プライベートにすると、クラスのすべての将来のバージョンに、同じことを行う同じ名前の同じメソッドが含まれることが事実上保証されます。ニーズが変化し、クラスの将来のバージョンが現在のメソッドとまったく同じように機能するメソッドを必要としない場合、プライベートメソッドはクラスの新しいニーズをよりよく満たすメソッドに安全に置き換えられる可能性があります。簡単な例として、クラスは文字列を取り、のような置換を実行するメソッド必要があると<する&lt;...それが書き込まれると、などを
supercat

1
...渡される文字列にはアンパサンドが含まれないことがわかっているため&&amp;[コードを記述&&amp;ている場合、必要だとは思わなかったとしても変換しますが、ありません]。それはそれは、後にアンパサンドを処理するために必要となりますが、この方法は、それが拡大して変化する、公開されている&ために&amp;、独自の実行外コード壊れる可能性があり&-to- &amp;置換を。ただし、メソッドがプライベートの場合、&外部コードに問題を引き起こすことなく処理するように修正できます。
supercat

それは控えめに言っても興味深い問題ですが、静的であることが、この問題の鍵である静的でないことよりも、どのように問題になるのかわかりません。私たちがあなたの論理に従えば、「どこかでバグや要件がいつか変わったらどうする?」という理由で、どこでもすべてがすべてを再実装します。
corsiKa 14

26

かなり一般的な理由(Javaの場合)は、単純なprivate staticメソッドを使用してコンストラクターの混乱を減らすことにより、コンストラクターで不変フィールド変数を初期化することです。

  • それはprivate:外部クラスはそれを見るべきではありません。
  • それはstatic、それはいくつかの操作を行うことができます独立した:1ホストクラスの状態に。

やや不自然な例が続きます...

例えば:

public class MyClass{
    private final String concatenated;

    public MyClass(String a, String b){
        concatenated = concat(a,b);
    }

    public String getConcatenated(){
       return concatenated;
    }

    /**
    *  Concatenates two Strings as `s1---s2`
    **/
    private static final String concat(String s1, String s2){
        return String.format("%s---%s", s1, s2);
    }
}

1 他のstatic変数との相互作用がないと仮定します。


15
これは、派生(計算)引数をスーパークラスのコンストラクターに渡す必要がある場合にさらに役立ちます。super(...)あなたはスーパーの呼び出しに渡すものをうまく支援するために、ローカル変数を宣言することはできませんので、呼び出しは、あなたのクラスのコンストラクタの最初の行でなければなりません。ただし、(プライベート)静的メソッドを呼び出すことができます。このメソッドは、スーパーコンストラクターに渡す値を計算するために必要な行を使用します。
アンドジェジドイル14

静的初期化ブロックの可能性があることに注意してください
フランツエブナー14

13

private staticメソッドの一般的なユースケースは、ユーティリティメソッドです

  1. その1つのクラスでのみ使用されます
  2. そのクラスの内部状態に依存しない

12

多くのメソッドで数行のコードが繰り返されていることがわかります。そのため、重複したコードは適切ではないため、それらを単一のメソッドに抽出することにします。

このメソッドは広く使用されるように設計されていないため、メソッドをプライベートにし、無関係なコードを呼び出すことは望ましくありません。(コメントでこの点を議論します…。)

メソッドはインスタンスフィールドにアクセスしないため、静的にすることができます。静的にすると、理解しやすくなり、少し速くなる場合もあります。

その後....(たぶん今、多分後で、多分決して)

メソッドを静的にすると、クラスからユニティクラスに移動できることは明らかです。

また、パラメータの1つのインスタンスメソッドに変換するのも簡単です。多くの場合、これはコードがあるべき場所です。


私はこの答えが好きですが、これに関する最新のリファレンスはありますか?「そして、おそらく少し速い」
マグニレックス

@Magnilex、「this」ポインターは静的クラスメソッドに渡されないため、コンパイラがインスタンスメソッドで「this」が使用されていないことを検出しない限り、静的インスタンスメソッドよりも高速になる傾向があります。
イアン

2

クラスで静的プライベートメソッドが必要になる理由は、少なくとも2つ考えられます。

1:インスタンスは、クラスのすべてのインスタンス間でデータを共有するため、直接呼び出されたくない静的メソッドを呼び出す理由があります。

2:パブリック静的メソッドには、直接呼び出されたくないサブルーチンがあります。このメソッドは、直接ではなく、インスタンスなしで呼び出されます。

もちろん、「クラスの意味を理解するのに役立ちます」というのは、それ自体が素晴らしい理由です。


1

一般に、プライベート静的メソッドを作成していることに気付いた場合は、個別にモデル化する必要があるものがあることを示すものと見なします。

特定のオブジェクトインスタンスの状態に関連付けられていないため、パブリックおよびプライベートの静的メソッドのコレクションは、独自のセマンティクスと非静的メソッドを備えた完全に独立したクラスを形成できます。

(別のヒントは、すべてが特定のタイプの共通パラメーターを持っている静的メソッド(パブリックおよびプライベート)をたくさん持っている場合、そのタイプのメンバーとしてより良いかもしれません。)

したがって、質問に答えるために、クラスがそのクラスのインスタンスに依存しない関連メソッドのグループを提供するときに、プライベート静的メソッドが表示されます。(...そして独立しているので、彼らは自分のクラスでより良いかもしれません。)


-1

私が考えることができる非常に単純な例は、メイン関数に渡される入力引数に対して何らかの処理(または何らかの操作)を行いたい場合です。したがって、この場合、処理が大きく、同じ機能が他のどこでも使用されない場合、プライベート関数を使用することは理にかなっています。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.