1. 静的メソッド

静的変数に加えて、クラスには静的メソッドを持つこともできます。

通常のメソッドはクラスのオブジェクト (インスタンス) にバインドされており、クラスの通常の (非静的) 変数 (静的変数およびメソッドも同様) を参照できます。静的メソッドはクラスの静的オブジェクトにバインドされており、クラスの静的変数や他の静的メソッドにのみアクセスできます。

クラスの通常の (非静的) メソッドを呼び出すには、まずクラスのオブジェクトを作成し、次にそのオブジェクトのメソッドを呼び出す必要があります。オブジェクトではなくクラスに対して通常のメソッドを呼び出すことはできません。

例:

クラスで非静的メソッドを呼び出すことはできません。
public class DataInfo
{
   public int getValue()
   {
      return 100;
   }
}

public class Solution
{
   public static void main(String[] args)
   {
      System.out.println(DataInfo.getValue()); // This will generate an error!
   }
}

ただし、静的メソッドを呼び出すには、クラスの静的オブジェクトが存在するだけで十分です (クラスがメモリにロードされた後も静的オブジェクトは常に存在します)。main() メソッドが静的であるのはこのためです。これはクラスの静的オブジェクトにバインドされているため、それを呼び出すためのオブジェクトを作成する必要はありません。

メソッドを static として宣言するには、メソッド ヘッダーの前に static キーワードを記述する必要があります。この構造の一般的な外観は次のとおりです。

static Type name(parameters)
{
   method code
}

例:

コード ノート
public class Solution
{
   public static void main(String args[])
   {
      test();
   }

   public static void test()
   {
      int d = 2/0;
   }
}


Java マシンは、main次のようなコマンドを使用してメソッドを呼び出しますSolution.main()



静的test()メソッドは静的main()メソッド内で呼び出されます。

別のクラスから静的メソッドを呼び出すには、静的メソッドの名前の前にクラス名を指定する必要があります。この構造の一般的な外観は次のとおりです。

Type name = ClassName.methodName(arguments)

例:

コード 静的メソッド
int x = Math.min(a, b);
int min(int a, int b)
Thread.sleep(200);
void sleep(long ms)
Path path = Path.of("c:\\readme.txt");
Path of(String str)


2. 静的メソッドと通常の (非静的) メソッド

静的メソッドと通常のメソッドの違いは何ですか?

通常のメソッドは通常のオブジェクト (クラスのインスタンス) にバインドされますが、静的メソッドはバインドされません。通常のメソッドはインスタンス内の変数にアクセスできますが、静的メソッドはアクセスできません。単に関連付けられたインスタンスがないからです。

2 種類のメソッドの違いを次の表に示します。

能力・財産 通常の方法 静的メソッド
クラスのインスタンスにバインドされる はい いいえ
クラスの通常のメソッドを呼び出すことができます はい いいえ
クラスの静的メソッドを呼び出すことができます はい はい
クラスの通常の変数にアクセスできます はい いいえ
クラスの静的変数にアクセスできる はい はい
オブジェクトに対して呼び出すことができます はい はい
クラスに呼び出すことができます いいえ はい

非常に厳しく制限されているのに、なぜそのような方法が必要なのでしょうか? 答えは、このアプローチにも利点があるということです。

まず、静的メソッドと変数にアクセスするためにオブジェクト参照を渡す必要はありません。

次に、変数のインスタンスが 1 つだけ必要な場合があります。たとえば、System.out( System クラスの静的 out 変数)。

そして 3 番目に、オブジェクトを作成する前にメソッドを呼び出す必要がある場合があります。たとえば、Java マシンは、クラスのインスタンスが作成される前であっても、main() メソッドを呼び出してプログラムの実行を開始します。

クラスのインスタンスにバインドされる

通常のメソッドが呼び出されるとき、引数 (メソッドが呼び出されるオブジェクト) が暗黙的にメソッドに渡されます。このパラメータは と呼ばれますthis この暗黙的なパラメーター (メソッドが呼び出されるオブジェクトへの参照) は、通常のメソッドと静的なメソッドを区別します。

静的メソッドにはこの暗黙的なパラメーターがないため、this静的メソッド内でキーワードを使用することはできません。また、静的メソッド内で非静的メソッドを呼び出すこともできません。クラスのインスタンスへの参照を取得する場所がまったくありません。

クラスの通常のメソッドを呼び出すことができます

通常のメソッドには常に暗黙的なthisパラメータがあるため、メソッドが呼び出されるオブジェクトへの参照が常に存在します。別の通常のメソッド内で通常のメソッドを呼び出すときは常に、thisその呼び出しを行うために暗黙的なパラメーターが使用されます。例

コード 使い方
int min(int a, int b)
{
   return a < b ? a : b;
}

int min(int a, int b, int c)
{
   int t = min(a, b);
   return min(t, c);
}
int min(int a, int b)
{
   return a < b ? a : b;
}

int min(int a, int b, int c)
{
   int t = this.min(a, b);
   return this.min(t, c);
}

そのため、静的メソッドから通常のメソッドを呼び出すことはできません。this静的メソッド内には暗黙的な変数の名前がありません。

あるいは、別の状況を想像してください。プログラム内でクラスのオブジェクトがまだ 1 つも作成されていません。クラスの静的メソッドを呼び出すことはできますか? はい。そして、この静的メソッドは通常の (非静的) メソッドを呼び出すことができますか?

さて、それをどのオブジェクトに呼び出すでしょうか? 結局のところ、私たちのクラスのインスタンスはまだ 1 つも存在していません。

クラスの静的メソッドを呼び出すことができます

静的メソッドはどこからでも、つまりプログラム内のどこからでも呼び出すことができます。これは、静的メソッドと通常のメソッドの両方から呼び出すことができることを意味します。ここには制限はありません。

クラスの通常の変数にアクセスできます

暗黙的なパラメーターを介してクラスのインスタンスへの参照を簡単に取得できるため、通常のメソッドからクラスの通常の変数にアクセスできますthis

静的メソッドは、通常の変数の値を取得するためにクラスのどのインスタンスを使用する必要があるかを知りません。さらに一般的には、静的メソッドが呼び出されても、プログラム内でクラスのインスタンスが 1 つも作成されていないという状況が簡単に発生します。

その結果、静的メソッドはクラスの通常の変数にアクセスできなくなります。

静的メソッドが通常のメソッドを呼び出すとします。その通常のメソッドはどのオブジェクトに対して呼び出されるべきでしょうか?

静的メソッド

誰も知らない!オブジェクトへの参照を渡さずに静的メソッドから通常のメソッドを呼び出すことができないのはこのためです。

クラスの静的変数にアクセスできる

静的変数の呼び出しの状況は、静的メソッドの呼び出しの場合と同じです。静的変数には、プログラム内のどこからでもアクセスできます。つまり、静的メソッドと通常のメソッドからアクセスできるということです。

オブジェクトに対して呼び出すことができます

静的メソッドと通常のメソッドの両方をオブジェクトに対して呼び出すことができます。通常のメソッド呼び出しが可能です。確かに、これが通常のメソッドを呼び出す唯一の方法です。オブジェクトに対して静的メソッドを呼び出すこともできます。この場合、コンパイラ自体が変数の型を決定し、その型に基づいて静的メソッドを呼び出します。

コード コンパイラはそれをどのように認識するか
Thread th = Thread.current();
th.sleep(1000);
Thread th = Thread.current();
Thread.sleep(1000);
Integer i = 1;
int x = i.parseInt("12");
Integer i = 1;
int x = Integer.parseInt("12");
"".valueOf(12);
String.valueOf(12);

クラスに呼び出すことができます

クラスでは静的メソッドのみを呼び出すことができます。通常のメソッドを呼び出すには、クラスのインスタンスへの参照が必要です。したがって、この構造を使用して通常のメソッドを呼び出すことはできません。ClassName.methodName(arguments)