静的メソッドをいつ使用するのか疑問に思いますか。いくつかのゲッターとセッターを持つクラス、1つか2つのメソッドがあり、それらのメソッドがそのクラスのインスタンスオブジェクトに対してのみ呼び出し可能であることを望みます。これは静的メソッドを使うべきだということですか?
例えば
Obj x = new Obj();
x.someMethod
または
Obj.someMethod
(これは静的な方法ですか?)
私はかなり混乱しています!
1つの経験則:「Objがまだ構築されていなくても、このメソッドを呼び出すことは意味がありますか?」と自問してください。もしそうなら、それは間違いなく静的でなければなりません。
そのため、Car
クラスでは静的なメソッドdouble convertMpgToKpl(double mpg)
を使用することができます。これは、誰もCarを作成したことがない場合でも、35mpgが何に変換されるのかを知りたい場合があるためです。しかしvoid setMileage(double mpg)
(ある特定のCarの効率を設定する)は、Carが構築される前にこのメソッドを呼び出すことは考えられないため、静的にはできません。
(しかし、その逆は必ずしも真ではありません。時には2つのCar
オブジェクトを含むメソッドを持っていて、それを静的にしたいと思うかもしれません。例えばCar theMoreEfficientOf( Car c1, Car c2 )
。これは非静的バージョンに変換できますが、どちらのCarがより重要であるかの「特権的」な選択はないので、呼び出し元に、メソッドを呼び出すオブジェクトとして1台のCarを選択させるべきではありません。しかし、メソッド。
以下のシナリオでのみ静的メソッドを定義します。
静的メソッドを使用する正当な理由がいくつかあります。
パフォーマンス:コードを実行したいが、そのために余分なオブジェクトをインスタンス化したくない場合は、静的メソッドに移します。 JVMは静的メソッドを最適化することもできます(静的メソッドは同じくらい高速ですがソースを見つけることができなかったので、私はかつてJames GoslingがあなたがJVMにカスタム命令を必要としないと宣言して読んだことがありますそれは完全に間違っているかもしれません)。はい、それはマイクロ最適化であり、おそらく不要です。そして、私たちのプログラマは、クールだからといって不要なことをすることはありませんよね。
実用性:new Util().method(arg)
を呼び出す代わりに、静的インポートでUtil.method(arg)
、またはmethod(arg)
を呼び出します。簡単、短く.
メソッドを追加する:あなたは本当にStringクラスにremoveSpecialChars()
インスタンスメソッドを持たせたかったのですが、そうではありません(そしてあなたのプロジェクトの特殊文字は他のものと違うかもしれないので(Javaはやや健全なので)追加することはできないので、ユーティリティクラスを作成し、removeSpecialChars(s)
の代わりにs.removeSpecialChars()
を呼び出します。甘い。
純度:いくつかの注意を払うと、静的メソッドは 純粋な関数 になります。それが依存するのはそのパラメータです。データ入力、データ出力継承の問題を心配する必要がないため、これは読みやすくデバッグしやすいです。あなたはインスタンスメソッドでもそれを行うことができますが、コンパイラは(インスタンス属性への参照を許可しないこと、メソッドをオーバーライドすることなどによって)静的メソッドであなたをもう少し助けます。
シングルトンを作成したい場合は静的メソッドも作成する必要がありますが、しないでください。つまり、二度考えてください。
さらに重要なことに、なぜが静的メソッドを作成したくないのでしょうか。基本的に、ポリモーフィズムはウィンドウの外に出ます。メソッドをオーバーライドすることはできません。 インタフェースで宣言することも (Java 8以前)。それはあなたのデザインから多くの柔軟性を取り除きます。また、状態が必要な場合は、同時実行性のバグやボトルネックがあるので注意が必要です。 。
Miskoの記事を読んだ後、 静的メソッド はテストの観点からは悪いと思います。代わりに ファクトリ が必要です(おそらく Guice のような依存性注入ツールを使用します。 ).
「どちらか一方だけを持つようにするにはどうすればよいですか」という問題は、うまく回避できます。メインのインスタンスは1つのApplicationFactoryのみをインスタンス化します。その結果、すべてのシングルトンのインスタンスは1つだけインスタンス化されます。
静的メソッドの基本的な問題はそれらが手続き型コードであるということです。手続き型コードをユニットテストする方法がわかりません。単体テストでは、自分のアプリケーションの一部を個別にインスタンス化できると想定しています。インスタンス化中、私は依存関係をモック/フレンドリと結び付けます。これは実際の依存関係を置き換えます。手続き型プログラミングでは、オブジェクトが存在しないため、 "ワイヤリング"するものは何もありません。コードとデータは別々です。
static
メソッドは、呼び出されるためにオブジェクトを初期化する必要がないメソッドの一種です。 Javaのstatic
関数でmain
が使用されていることに気付きましたか?プログラムの実行は、オブジェクトが作成されずにそこから始まります。
次の例を見てください。
class Languages
{
public static void main(String[] args)
{
display();
}
static void display()
{
System.out.println("Java is my favorite programming language.");
}
}
Javaの静的メソッドはクラスに属します(そのインスタンスではありません)。これらはインスタンス変数を使用せず、通常はパラメータから入力を受け取り、それに対してアクションを実行してから何らかの結果を返します。インスタンスメソッドはオブジェクトに関連付けられており、名前が示すようにインスタンス変数を使用できます。
いいえ、静的メソッドはインスタンスに関連付けられていません。彼らはその階級に属しています。静的メソッドはあなたの2番目の例です。インスタンスメソッドが最初です。
静的キーワードを任意の方法で適用する場合、それは静的方法と呼ばれます。
//すべてのオブジェクトの共通プロパティを変更するプログラム(静的フィールド)。
class Student9{
int rollno;
String name;
static String college = "ITS";
static void change(){
college = "BBDIT";
}
Student9(int r, String n){
rollno = r;
name = n;
}
void display (){System.out.println(rollno+" "+name+" "+college);}
public static void main(String args[]){
Student9.change();
Student9 s1 = new Student9 (111,"Indian");
Student9 s2 = new Student9 (222,"American");
Student9 s3 = new Student9 (333,"China");
s1.display();
s2.display();
s3.display();
} }
O/P:111インドBBDIT 222アメリカBBDIT 333中国BBDIT
静的メソッドはインスタンスに関連付けられていないため、クラス内の非静的フィールドにはアクセスできません。
メソッドがクラスのフィールド(または静的フィールドのみ)を使用しない場合は、静的メソッドを使用します。
クラスの非静的フィールドが使用されている場合は、非静的メソッドを使用する必要があります。
実際には、プログラムの一部を使用したい場合は、プログラム内で静的プロパティとメソッドをクラス内で使用します。また、静的プロパティを操作するには、インスタンス変数の一部ではないため、静的メソッドが必要であることがわかります。そして静的メソッドがなければ、静的プロパティを操作するのは時間がかかります。
静的メソッドはクラスで呼び出され、インスタンスメソッドはクラスのインスタンスで呼び出されるべきです。しかし、それは実際にはどういう意味ですか?これは便利な例です。
自動車クラスには、Accelerate()というインスタンスメソッドがあります。車が実際に存在する(建設されている)場合は、車を加速することしかできません。したがって、これはインスタンスメソッドになります。
自動車クラスには、GetCarCount()というcountメソッドもあります。これは、作成(または建設)された自動車の総数を返します。自動車が建設されていない場合、このメソッドは0を返しますが、それでも呼び出すことができるはずなので、静的メソッドにする必要があります。
クラスのインスタンスなしでメソッドにアクセスできるようにしたい場合は、静的メソッドを使用します。
静的メソッドはオブジェクトに対して呼び出す必要はありません。それはあなたがそれを使うときです。例:あなたのMain()は静的であり、あなたはそれを呼び出すためのオブジェクトを作成しません。
静的メソッドと変数は、Javaの 'Global'関数と変数の制御バージョンです。どのメソッドにclassname.methodName()
またはclassInstanceName.methodName()
としてアクセスできるか、つまり静的メソッドおよび変数には、クラス名とクラスのインスタンスを使用してアクセスできます。
クラスをstaticとして宣言することはできません(クラスがpublicとして宣言されている場合は、どこからでもアクセスできるため、意味がありません)。内部クラスはstaticとして宣言できます。
以下の場合は静的メソッドを使用できます。
インスタンスに対してアクションを実行したくない場合(ユーティリティメソッド)
この記事では上記の回答のいくつかで述べたように、マイルをキロメートルに変換したり、気温を華氏から摂氏に、あるいはその逆に計算したりします。静的メソッドを使用したこれらの例では、ヒープメモリ内の新しいオブジェクト全体をインスタンス化する必要はありません。以下を検討してください
1. new ABCClass(double farenheit).convertFarenheitToCelcium()
2. ABCClass.convertFarenheitToCelcium(double farenheit)
前者はすべてのメソッド呼び出しに対して新しいクラスフットプリントを作成します。パフォーマンス、実用的。例としては、以下のMathライブラリとApache-CommonsライブラリのStringUtilsクラスがあります。
Math.random()
Math.sqrt(double)
Math.min(int, int)
StringUtils.isEmpty(String)
StringUtils.isBlank(String)
簡単な機能として使いたい。入力は明示的に渡され、結果データを戻り値として取得します。継承、オブジェクトのインスタンス化は考えられません。 簡潔で読みやすい。
NOTE:静的メソッドのテスト容易性を主張する人はほとんどいませんが、静的メソッドもテストできます。 jMockitを使えば、静的メソッドをモックすることができます。 テスト容易性。以下の例:
new MockUp<ClassName>() {
@Mock
public int doSomething(Input input1, Input input2){
return returnValue;
}
};
静的:Obj.someMethod
メソッドへのクラスレベルのアクセスを提供したい場合、つまりメソッドがクラスのインスタンスなしで呼び出し可能でなければならない場合、static
を使用します。
静的メソッドは、クラスのオブジェクトを作成せずに呼び出すことができるJavaのメソッドです。それはクラスに属しています。
インスタンスを使用してメソッドを呼び出す必要がない場合は、静的メソッドを使用します。
静的メソッドには、主に2つの目的があります。
静的メソッドをいつ使用するのか疑問に思いますか。
static
メソッドの一般的な用途はstatic
フィールドへのアクセスです。しかし、static
変数を参照せずにstatic
メソッドを持つことができます。 static
変数を参照しないヘルパーメソッドは、 Java.lang.Math のようないくつかのJavaクラスにあります。
public static int min(int a, int b) {
return (a <= b) ? a : b;
}
他の使用例として、synchronized
メソッドと組み合わせたこれらのメソッドがマルチスレッド環境でのクラスレベルロックの実装であると考えることができます。
いくつかのゲッターとセッターを持つクラス、1つか2つのメソッドがあり、それらのメソッドがそのクラスのインスタンスオブジェクトに対してのみ呼び出し可能であることを望みます。これは静的メソッドを使うべきだということですか?
クラスのインスタンスオブジェクトのmethodにアクセスする必要がある場合、そのメソッドはstaticではないはずです。
詳細については、Oracleのドキュメント のページ を参照してください。
インスタンス変数とクラス変数、およびメソッドのすべての組み合わせが許可されているわけではありません。
静的メソッドが適切な場合
静的メソッドまたは静的変数が使用されているのは2つの状況のみであり、それは憎悪ではありません。
静的メソッドが悪いとき?
静的メソッドについて考える1つの方法は、グローバルプロシージャとしてです。基本的に、静的メソッドはどこからでもどこでも呼び出すことができます。実際にクラスが「タグ」としてのみ使用される場合、クラスの一部のふりをして、メソッドを論理的な分割によって整理します。グローバルプロシージャの作成は、オブジェクト指向設計の正反対だからです。
静的メソッドのもう1つの大きな問題は、テスト容易性です。ソフトウェアを構築する場合、テスト容易性は大きな問題です。静的メソッドは、特に具象クラスの新しいインスタンスを作成する場合、テストが難しいことで有名です。従来のコードで作業したことがあり、静的メソッドの単体テストを作成しようとしたことがあるなら、あなたは私の痛みを知っています。
静的メソッドもポリモーフィックではありません。クラスで静的メソッドを作成する場合、その動作をオーバーライドすることはありません。その実装へのハードコード化された参照で立ち往生しています。
最終単語
したがって、静的メソッドを作成するときは、慎重に検討することを忘れないでください。私はそれらを決して使用しないことを主張していません。私は本当に正当な理由があると主張し、最初に静的メソッドが本当に状態情報を使用できる別のクラスに属しているかどうかを確認するためにチェックしています。