回答:
経験則:「オブジェクトがまだ作成されていなくても、このメソッドを呼び出すことは理にかなっていますか?」もしそうなら、それは間違いなく静的でなければなりません。
したがって、クラスにCar
はメソッドがある場合があります。
double convertMpgToKpl(double mpg)
...これは静的です。なぜなら、誰もを作成したことがなくても、35mpgが何に変換されるのかを知りたい場合があるからCar
です。しかし、この方法(ある特定のの効率を設定するCar
):
void setMileage(double mpg)
... Car
構成する前にメソッドを呼び出すことは考えられないため、静的にすることはできません。
(ちなみに、その逆は常に正しいとは限りません。2つのCar
オブジェクトを含むメソッドがあり、それを静的にしたい場合があります。例:
Car theMoreEfficientOf( Car c1, Car c2 )
これは非静的バージョンに変換される可能性がありますが、「特権付き」の選択肢Car
はより重要ではないため、呼び出し元にCar
、呼び出すオブジェクトとして強制的に選択させるべきではないと主張する人もいます。メソッドオン。ただし、この状況は、すべての静的メソッドのごく一部を占めています。)
Car#isMoreEfficientThan(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つだけ持つ「何かを1つだけ持っていることをどのように確認するか」という問題はうまく回避されます。メインで単一のApplicationFactoryのみをインスタンス化すると、すべてのシングルトンの単一のインスタンスのみがインスタンス化されます。
静的メソッドの基本的な問題は、それらが手続き型コードであることです。手続き型コードを単体テストする方法がわかりません。単体テストでは、アプリケーションの一部を分離してインスタンス化できると想定しています。インスタンス化中に、依存関係を実際の依存関係を置き換えるモック/フレンドリーに関連付けます。手続き型プログラミングでは、オブジェクトがなく、コードとデータが分離されているため、「配線」するものはありません。
Math.abs()
Arrays.sort()
Arrays.sort()
Math.abs()
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()というカウントメソッドも含まれる場合があります。これにより、作成(または作成)された車の総数が返されます。車が構築されていない場合、このメソッドは0を返しますが、それでも呼び出すことができるはずなので、静的メソッドでなければなりません。
実際、クラスで静的プロパティとメソッドを使用します。プログラムを実行するまで、プログラムの一部を使用したい場合はそこに存在する必要があります。また、静的プロパティを操作するには、インスタンス変数の一部ではないため、静的メソッドが必要であることがわかります。また、静的メソッドがないと、静的プロパティを操作するのに時間がかかります。
静的メソッドは、オブジェクトで呼び出す必要はありません。それは、それを使用するときです。例:Main()は静的であり、それを呼び出すオブジェクトを作成しません。
静的メソッドは次の場合に使用できます
インスタンス(ユーティリティメソッド)でアクションを実行したくない
この投稿の上記の回答のいくつかで述べたように、マイルをキロメートルに変換するか、気温を華氏から摂氏に、またはその逆に計算します。静的メソッドを使用するこれらの例では、新しいオブジェクト全体をヒープメモリにインスタンス化する必要はありません。以下を検討
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)
シンプルな機能として使いたい。入力が明示的に渡され、結果データが戻り値として取得されます。継承、オブジェクトのインスタンス化は実現しません。簡潔で読みやすい。
注:静的メソッドのテスト可能性に反対する人はほとんどいませんが、静的メソッドもテストできます!jMockitを使用すると、静的メソッドをモックできます。テスト容易性。以下の例:
new MockUp<ClassName>() {
@Mock
public int doSomething(Input input1, Input input2){
return returnValue;
}
};
静的メソッドをいつ使用するのですか?
static
メソッドの一般的な用途は、static
フィールドへのアクセスです。しかしstatic
、static
変数を参照せずにメソッドを持つことができます。static
変数を参照しないヘルパーメソッドは、java.lang.Mathなどの一部のJavaクラスにあります。
public static int min(int a, int b) {
return (a <= b) ? a : b;
}
もう1つの使用例として、これらのメソッドをメソッドと組み合わせるとsynchronized
、マルチスレッド環境でのクラスレベルのロックの実装が考えられます。
いくつかのゲッターとセッター、またはメソッドを1つまたは2つ持つクラスがあり、それらのメソッドをクラスのインスタンスオブジェクトでのみ呼び出し可能にしたいとします。これは、静的メソッドを使用する必要があることを意味しますか?
クラスのインスタンスオブジェクトのメソッドにアクセスする必要がある場合、メソッドは非静的である必要があります。
詳細については、Oracleのドキュメントページを参照してください。
インスタンス変数とクラス変数およびメソッドのすべての組み合わせが許可されるわけではありません。
A common use for static methods is to access static fields.
は議論ではありません。
コードでメソッドを呼び出すオブジェクトを作成したくない場合は、そのメソッドを静的として宣言するだけです。静的メソッドはインスタンスを呼び出す必要がないため、ここでのキャッチはすべての静的メソッドがJVMによって自動的に呼び出されるわけではないためです。この特権は、Javaのmain() "public static void main [String ... args]"メソッドによってのみ享受されます。これは、実行時にこれが、JVMがエントリポイントとして求めるメソッドSignature public "static" void main []であるためです。コードの実行を開始します。
例:
public class Demo
{
public static void main(String... args)
{
Demo d = new Demo();
System.out.println("This static method is executed by JVM");
//Now to call the static method Displ() you can use the below methods:
Displ(); //By method name itself
Demo.Displ(); //By using class name//Recommended
d.Displ(); //By using instance //Not recommended
}
public static void Displ()
{
System.out.println("This static method needs to be called explicitly");
}
}
出力:-この静的メソッドはJVMによって実行されますこの静的メソッドは明示的に呼び出す必要がありますこの静的メソッドは明示的に呼び出す必要がありますこの静的メソッドは明示的に呼び出す必要があります