は民間の介助方法に静電気の帯びにくくなるのです静
-
22-08-2019 - |
質問
ちんのアクティビティにはインスタンスを生成できる.私は複数のプライベート"のヘルパー"法の内部クラスを必要としないアクセスのクラス会員はその引数を返します。
public class Example {
private Something member;
public double compute() {
double total = 0;
total += computeOne(member);
total += computeMore(member);
return total;
}
private double computeOne(Something arg) { ... }
private double computeMore(Something arg) {... }
}
が、特に理由を指定し computeOne
や computeMore
としてstaticメソッドまたは特定の理由は何ですか?
確かに簡単離して非静的なものが必ず静ながります。
解決
私はprivate static
するために、このようなヘルパーメソッドを好みます。これは、彼らがオブジェクトの状態を変更しません読者にそれを明確にします。私のIDEはまた、私はこの方法で署名を見ずに静的である知っているだろう、イタリック体の静的メソッドの呼び出しが表示されます。
他のヒント
この結果、少し小さめbytecodeは、staticメソッドなアクセス this
.とは思わないので違い速度とした場合はおもしろくするのもいいけど小さすぎて作りを通して総合).
ただ静かはなします。った。
編集: この答えを続けており、また、downvotedあり、主張の根拠のないbytecodeサイズです。そのままに実際にテストです。
class TestBytecodeSize {
private void doSomething(int arg) { }
private static void doSomethingStatic(int arg) { }
public static void main(String[] args) {
// do it twice both ways
doSomethingStatic(0);
doSomethingStatic(0);
TestBytecodeSize t = new TestBytecodeSize();
t.doSomething(0);
t.doSomething(0);
}
}
Bytecode(検索 javap -c -private TestBytecodeSize
):
Compiled from "TestBytecodeSize.java"
class TestBytecodeSize extends java.lang.Object{
TestBytecodeSize();
Code:
0: aload_0
1: invokespecial #1; //Method java/lang/Object."<init>":()V
4: return
private void doSomething(int);
Code:
0: return
private static void doSomethingStatic(int);
Code:
0: return
public static void main(java.lang.String[]);
Code:
0: iconst_0
1: invokestatic #2; //Method doSomethingStatic:(I)V
4: iconst_0
5: invokestatic #2; //Method doSomethingStatic:(I)V
8: new #3; //class TestBytecodeSize
11: dup
12: invokespecial #4; //Method "<init>":()V
15: astore_1
16: aload_1
17: iconst_0
18: invokespecial #5; //Method doSomething:(I)V
21: aload_1
22: iconst_0
23: invokespecial #5; //Method doSomething:(I)V
26: return
}
メソッドを呼び出して、静的メソッドは二つのバイトコード(byteops?): iconst_0
(引き) invokestatic
.
メソッドを呼び出して、非staticメソッドは三: aload_1
( TestBytecodeSize
オブジェクトだと思), iconst_0
(引き) invokespecial
.(注がれなかった私の方法ではないでしょうか invokevirtual
の代わりに invokespecial
;見 環太平洋§7.7を呼び出す方法.)
現在、先ほど言ったように、私が見つからないあるのは、大きな差間のパフォーマンスにこれら以外のこと invokestatic
ター中の開催は難しい状況ですが少ないbytecode. invokestatic
や invokespecial
るべき若干速くしな invokevirtual
, それは、その両方を利用静的結合の代わりにダイナミックだが、わからない場合があります。いない参照です。最も近いのでは この1997年JavaWorld第, 基本的にはrestates私が述べたとおり:
最速の指示ができ
invokespecial
やinvokestatic
, な方法によって呼び出されるこの説明は静的に行します。のJVMを解決す象徴的な参照はこれらの指示を置き換えることで直接参照が直接参照であろうとなどを指すポインタの実際のバイトコード.
多くのものは変わったのは1997年のことである。
で、結局...これやってもこだわりってしまう。速度などを理由に選べるのですマイクロ-最適化しました。
私の個人的な好みは、それは彼らがステートレスだクリアフラグだとして、静的に宣言することです。
答えは...それは異なります。
メンバーは、あなたが扱っているオブジェクトにインスタンス変数の特定の場合には、なぜすべてで、それをパラメータとして渡す?
たとえばます:
public class Example {
private Something member;
public double compute() {
double total = 0;
total += computeOne();
total += computeMore();
return total;
}
private double computeOne() { /* Process member here */ }
private double computeMore() { /* Process member here */ }
}
this
またはsuper
「前」クラスのコンストラクタでそれらを呼び出すために必要がある場合は、あなたは、静的なヘルパーメソッドを宣言することがあります一つの理由です。たとえばます:
public class MyClass extends SomeOtherClass {
public MyClass(String arg) {
super(recoverInt(arg));
}
private static int recoverInt(String arg) {
return Integer.parseInt(arg.substring(arg.length() - 1));
}
}
これは不自然な例のビットであるが、明確recoverInt
この場合のインスタンスメソッドにすることはできません。
できないと思っている明確な優位性のための民間の静的な方法です。とはいえ、ありません特定のメリットも非静ます。この主題発表:いて静的を明確に強調していることがないの変更オブジェクトです。
のための方法の異なるアクセス権限もあると思うが、主に二つの引数:
- 静的メソッドを呼び出を作成せずにオブジェクトのインスタンスできる有
- 静的メソッドできないものを受け継ぎ、可能な問題が必要な場合は多型では無関係な個人ます。
この違いは、寒さをしてみたいと強く思ったからに違いるようなこのポインタを渡したインスタンスメソッドの重差です。
正解はあります:
フィールドから任意の情報を取らないと、フィールドに任意の情報を入れていない任意の方法では、インスタンスメソッドである必要はありません。そのクラスまたはオブジェクト内の任意のフィールドを使用するか、または変更されることはありません任意の方法は、同様に、静的な方法かもしれません。
、または任意の特定の理由に[として静的に宣言]ない?の
はいます。
インスタンスメソッドとしてそれらを保持することによって、あなた自身が後で別の実装を提供することができます。
それは愚かに聞こえるかもしれ(およびそれらのメソッドが50行プログラムにだけで使用されている場合、実際にそれが可能だろう)が、大規模なアプリケーションで、または他の誰かが使用するライブラリで、あなたはより良い実装を選択することを決定するかもしれませんが、既存のコードを壊したくない。
あなたはサブクラスを作成し、新しいバージョンではそれを返し、メソッドがインスタンスメソッドとして宣言されたので、あなただけの多型がその仕事をやらせるようにします。
また、あなたはコンストラクタはプライベート作るの恩恵を受けると同じ理由のための静的なファクトリメソッドを提供することができます。
だから、私の推薦は、インスタンスメソッドとしてそれらを維持し、可能な場合は、静的避けるためです。
言語が提供するダイナミズムを活用します。
多少の関連動画はこちらを参照してください:良いAPIと、なぜそれが事態を設計する方法A>
それが直接「静的インスタンス対」法の議論とは関係ありませんが、、それはAPIの設計では、いくつかの興味深い点について触れています。
静的メソッドを持っていることについて1つの問題は、それが にユニットテストで使用するオブジェクトをより困難にすることができるということです。 Mockitoは、静的メソッドのモックを作成することはできませんし、メソッドのサブクラス実装を作成することはできません。
この方法は、基本的に予見それは静的な宣言、状態情報を使用することはありませんちょうどサブルーチンである場合。
これはすなわち、それは他の静的メソッドまたはクラス初期化に使用されることを可能にする:
public class Example {
//...
//Only possible if computeOne is static
public final static double COMPUTED_ONE = computeOne(new Something("1"));
//...
}
このような場合での私の好みはcomputeOne
を作成し、静的メソッドをcomputeMore
することです。理由:カプセル化。あなたのクラスの実装へのアクセスを持っているより少ないコード、より良います。
あなたが与える例では、computeOne
and computeMore
は、クラスの内部にアクセスする必要があるので、なぜクラスのメンテナは、内部に干渉するするための機会を与えるべきではないと述べている。
私は他のポスターはそのが間違った情報を与えるよう言ってきたいくつかのことを明確にしたいと思います。
メソッドがプライベートであるため、まず、あなたがそれらを静的に宣言する場合でも、あなたは、このクラスの外でそれらにアクセスすることはできません。第二に、彼らはプライベートなので、あなたはそうであっても、静的なサブクラスまたは任意の違いを確認しない非静的に上書きすることはできません。第三に非静的プライベートメソッドも、それは静的である必要はなく、クラスのコンストラクタから呼び出すことができます。
プライベートヘルパーメソッドは、静的または非静的として定義されなければならない場合は、は、今、あなたの質問に来ます。プライベートメソッド静的をマーキング私はコーディング時に私も、このルールに従うように、この方法はステートレスであることを示しているように私はスティーブの答えとなります。
経験から私は、このような民間の方法は非常に普遍的で再利用可能になりがちと述べているでしょう。
私が最初に行うべきことは、この方法は、現在のクラスのコンテキストの外側に有用である可能性があるかどうか質問をすると思います。もしそうなら、私は誰もが示唆正確に何をすべきかと誰かがうまくいけば、まったく同じことをやって、新しいメソッドを実装する前にチェックするいくつかのutilsのクラスに静的このメソッドを抽出します。
各開発者が独立してちょうど彼女がそれを使用する必要がある場所でそれらを再発明するので、このような一般的な使用のプライベートな方法は、プロジェクト内のコードの重複の大部分のソースです。だから、このような方法の集中が進むべき道である。
静的/非静的質問が来るまで「私は本当にこのクラスのオブジェクトを使用する必要があります」?
だから、あなたはさまざまな方法間でオブジェクトを渡していますか?オブジェクトは、静的メソッドのコンテキスト外に役立つ情報が含まれていますか?あなたがそれらを両方の方法を使用します場合は方法両方の方法を定義しない何らかの理由はありますか?
あなたはこのジレンマにしている場合は、、あなたがオブジェクトの外にあなたのコードに漂っ方法のために必要なすべてのデータを持っているように私には思えます。これは、あなたの望むことですか?それだけで、常にオブジェクトにするたびにそのデータを収集するために容易になるだろうか?あなただけの単一のモデルにコミットする程度相反するかもしれません。あなたは一つの方法を使用して、それをすべて行うことができます場合は、静的または非静的のどちらかを選んで、それを持って行く。
具体的には、あなたが与えてくれた例に、あなたが機能のためよりも、それを読んでいるときに、これらのメソッドを定義する目的は、コード明確にするため、よりであると思われる(彼らは<全角> のプライベートとして定義されています) 。静的の目的は、クラスの機能を公開することであるので、その場合には、静的と一緒に行くことは本当に、あなたのために何もしません。
一つの理由は、他のすべての条件が同じ、静的メソッドの呼び出しが速くあるべき、ということです。静的メソッドは、仮想することはできません、この基準暗黙的になりません。
オフトピック:私はそれで唯一の静的メソッドで、スタンドアロンのユーティリティ/ヘルパークラスのヘルパーメソッドを保つだろう。
使用の時点でのヘルパーメソッドを持つとのトラブルが(「同じクラス」を読んで)はラインの下の誰かが同じ場所で自分は無関係のヘルパーメソッドを掲示することを選択するかもしれないということです。
class Whatever {
public static varType myVar = initializeClassVariable();
private static varType initializeClassVariable() {
//initialization code goes here
}
}
プライベート静的メソッドの利点を使用して、クラス変数を再初期化する必要がある場合、彼らは、後で再利用できるということです。
なにstatic修飾子ができなかの方法が状態などを分析することができますきの(再)を書く方法です。
その"静"の修飾してお考えいのリファクタリングのその他のものその他がunuseful.E.g.移動方法を一部のユーティリティクラスまたは変換でメンバーメソッド..
私は彼らのようにステートレスフラグにそれらを静的宣言します。
Javaはエクスポートされませんマイナーな操作のためのより良いメカニズムを持っていないので、私はプライベート静的が許容できると思います。
多くの人が言ったように、それはようである作るの の静的のの! ここで私は従う親指ルールがあります:あなたはメソッドがのそれはステートレスである。すなわち、=>(中[Eclipseの]何の青色VARSを任意のインスタンス変数を伴わないいないだけで、の数学関数であると考えられる場合法)、及び方法の結果は勿論同じパラメータを持つコールの「n」個の数()のために同じになり、その後、STATICとしてその方法をマークします。
そして、あなたは、このメソッドは他のクラスに有用であろうと思うならば、sameclassにプライベートとしてメソッドを入れ、それ以外の場合はUtilのクラスに移動します。 (アクセス可能性を最小限に抑える)