458

具体的には、次のコードを試していました。

package hello;

public class Hello {

    Clock clock = new Clock();

    public static void main(String args[]) {
        clock.sayTime();
    }
}

しかし、それはエラーを与えました

静的メソッド main の非静的フィールドにアクセスできません

そこで、の宣言を次のように変更しましたclock

static Clock clock = new Clock();

そしてそれはうまくいきました。そのキーワードを宣言の前に置くとはどういう意味ですか? そのオブジェクトに対して何ができるかという点で、正確には何を実行および/または制限しますか?

4

22 に答える 22

647

staticメンバーは、特定のインスタンスではなくクラスに属します。

これは、クラスのインスタンスを 100 万個作成しても、作成しなくても、フィールドのインスタンスは 1 つしか存在しないことを意味しますstatic[1] 。すべてのインスタンスで共有されます。

staticメソッドも特定のインスタンスに属していないため、インスタンス メンバーを参照できません。与えられた例では、クラスのどのインスタンス (したがって、クラスのどのインスタンス) を参照する必要がmainあるかわかりません。メンバーはメンバーのみを参照できます。インスタンス メンバーは、もちろんメンバーにアクセスできます。HelloClockstaticstaticstatic

補足:もちろん、メンバーはオブジェクト参照を通じてstaticインスタンス メンバーにアクセスできます。

例:

public class Example {
    private static boolean staticField;
    private boolean instanceField;
    public static void main(String[] args) {
        // a static method can access static fields
        staticField = true;

        // a static method can access instance fields through an object reference
        Example instance = new Example();
        instance.instanceField = true;
    }

[1]: ランタイムの特性によっては、ClassLoader または AppDomain またはスレッドごとに 1 つになることもありますが、それは問題ではありません。

于 2009-01-05T17:44:31.243 に答える
131

これは、「Hello」クラスの個別のインスタンスごとに 1 つではなく、Hello に「時計」のインスタンスが 1 つしかないことを意味します。つまり、すべてのインスタンス間で共通に共有される「時計」参照が 1 つあることを意味します。 「こんにちは」クラス。

したがって、コードの任意の場所で「new Hello」を実行する場合: A- 最初のシナリオ (変更前、「static」を使用しない) では、「new Hello」が呼び出されるたびに新しいクロックが作成されます。しかし、B- 2 番目のシナリオ (変更後、「静的」を使用) では、すべての「新しい Hello」インスタンスは、最初に作成された最初の同じ「クロック」参照を引き続き共有して使用します。

メイン以外のどこかで「クロック」が必要でない限り、これも同様に機能します。

package hello;
public class Hello
{
    public static void main(String args[])
    {
      Clock clock=new Clock();
      clock.sayTime();    
    }
}
于 2009-01-05T17:45:56.123 に答える
97

staticキーワードは、何か(フィールド、メソッド、またはネストされたクラス)が、型の特定のインスタンスではなく、に関連していることを意味します。したがって、たとえば、クラスのインスタンスなしで呼び出すと、実際にクラスのインスタンスを作成することはできませんMath.sin(...)MathMath

詳細については、OracleのJavaチュートリアルの関連ビットを参照してください。


サイドノート

残念ながら、Javaでは、静的メンバーにインスタンスメンバーであるかのようにアクセスできます。

// Bad code!
Thread.currentThread().sleep(5000);
someOtherThread.sleep(5000);

これにより、インスタンスメソッドのように見えますsleepが、実際には静的メソッドであり、常に現在のスレッドをスリープ状態にします。呼び出し元のコードでこれを明確にすることをお勧めします。

// Clearer
Thread.sleep(5000);
于 2009-07-04T06:35:47.447 に答える
42

Javaのキーワードは、変数または関数が、実際のオブジェクト自体ではなく、staticに属しているため、そのクラスのすべてのインスタンス間で共有されることを意味します。

したがって、変数がある場合: 1つのインスタンスでprivate static int i = 0;それをインクリメント(i++)すると、変更はすべてのインスタンスに反映されます。iすべてのインスタンスで1になります。

静的メソッドは、オブジェクトをインスタンス化せずに使用できます。

于 2009-07-04T06:26:07.993 に答える
27

静的メンバーの基本的な使い方...

public class Hello
{
    // value / method
    public static String staticValue;
    public String nonStaticValue;
}

class A
{
    Hello hello = new Hello();
    hello.staticValue = "abc";
    hello.nonStaticValue = "xyz";
}

class B
{
    Hello hello2 = new Hello(); // here staticValue = "abc"
    hello2.staticValue; // will have value of "abc"
    hello2.nonStaticValue; // will have value of null
}

これにより、クラス インスタンス Hello を他のクラスに送信せずに、すべてのクラス メンバーで値を共有できます。そして、静的なクラスインスタンスを作成する必要はありません。

Hello hello = new Hello();
hello.staticValue = "abc";

クラス名で静的な値またはメソッドを呼び出すことができます。

Hello.staticValue = "abc";
于 2014-03-13T18:26:41.230 に答える
22

静的とは、クラスに関連付けられたメソッドまたは変数を使用するためにクラスのインスタンスを作成する必要がないことを意味します。あなたの例では、次のように呼び出すことができます:

Hello.main(new String[]()) //main(...) is declared as a static function in the Hello class

直接、代わりに:

Hello h = new Hello();
h.main(new String[]()); //main(...) is a non-static function linked with the "h" variable

静的メソッド (クラスに属する) 内から、静的でないメンバーにはアクセスできません。これらの値は、クラスのインスタンス化に依存するためです。インスタンス メンバーである非静的 Clock オブジェクトは、Hello クラスのインスタンスごとに異なる値/参照を持つため、クラスの静的部分からアクセスできませんでした。

于 2009-01-05T17:45:52.037 に答える
21

Java の静的:

Static は非アクセス修飾子です。static キーワードは、クラスのインスタンスよりもクラスに属します。変数またはメソッドをクラスにアタッチするために使用できます。

static キーワードは以下で使用できます。

方法

変数

別のクラス内にネストされたクラス

初期化ブロック

使用できません:

クラス (ネストされていない)

コンストラクタ

インターフェース

Method Local Inner Class(ネストされたクラスとの違い)

内部クラス メソッド

インスタンス変数

ローカル変数

例:

コンストラクターでインクリメントされるcount という名前のインスタンス変数を持つ次の例を想像してください。

package pkg;

class StaticExample {
    int count = 0;// will get memory when instance is created

    StaticExample() {
        count++;
        System.out.println(count);
    }

    public static void main(String args[]) {

        StaticExample c1 = new StaticExample();
        StaticExample c2 = new StaticExample();
        StaticExample c3 = new StaticExample();

    }
}

出力:

1 1 1

インスタンス変数はオブジェクト作成時にメモリを取得するため、各オブジェクトはインスタンス変数のコピーを持つことになり、インクリメントしても他のオブジェクトには反映されません。

インスタンス変数カウントを静的変数に変更すると、プログラムは異なる出力を生成します。

package pkg;

class StaticExample {
    static int count = 0;// will get memory when instance is created

    StaticExample() {
        count++;
        System.out.println(count);
    }

    public static void main(String args[]) {

        StaticExample c1 = new StaticExample();
        StaticExample c2 = new StaticExample();
        StaticExample c3 = new StaticExample();

    }
}

出力:

1 2 3

この場合、静的変数は一度だけメモリを取得します。オブジェクトが静的変数の値を変更した場合、その値は保持されます。

最終的な静的:

final および staticとして宣言されたグローバル変数は、実行全体で変更されません。静的メンバーはクラス メモリに格納され、実行全体で 1 回だけ読み込まれるためです。それらはクラスのすべてのオブジェクトに共通です。static 変数を final として宣言すると、オブジェクトは final であるため値を変更できません。したがって、final および static として宣言された変数は、定数と呼ばれることがあります。インターフェイスのすべてのフィールドは、デフォルトで最終的で静的であるため、定数と呼ばれます。

ここに画像の説明を入力

画像リソース :最終静的

于 2016-08-14T13:03:23.113 に答える
16

既存の回答に追加するために、写真を試してみましょう:

すべての普通預金口座には 2% の利率が適用されます。したがって、それはstaticです。

バランスは個別である必要があるため、静的ではありません。

ここに画像の説明を入力

于 2016-07-18T07:32:54.627 に答える
13

この議論では、これまでクラスローダに関する考慮事項を無視してきました。厳密に言えば、Java 静的フィールドは、特定のclassloaderのクラスのすべてのインスタンス間で共有されます。

于 2009-01-05T18:14:03.477 に答える
7

キーワードstaticは、フィールドまたはメソッドがインスタンスではなくクラス自体に属していることを示すために使用されます。コードを使用すると、オブジェクトClockが静的な場合、HelloクラスのすべてのインスタンスがこのClockデータ メンバー (フィールド) を共有します。非静的にすると、 の個々のインスタンスごとHelloに一意のClockフィールドを持つことができます。

コードを実行できるように、メインメソッドをクラスに追加しました。Helloそれに関する問題は、メインメソッドが静的であるため、その中の非静的フィールドまたはメソッドを参照できないことです。これは、次の 2 つの方法で解決できます。

  1. クラスのすべてのフィールドとメソッドを静的にして、メインメソッドHello内で参照できるようにします。これは本当に良いことではありません (または、フィールドやメソッドを静的にする間違った理由です)。
  2. メイン メソッド内にクラスのインスタンスを作成Helloし、最初に意図した方法ですべてのフィールドとメソッドにアクセスします。

これは、コードに次の変更を加えることを意味します。

package hello;

public class Hello {

    private Clock clock = new Clock();

    public Clock getClock() {
        return clock;
    }

    public static void main(String args[]) {
        Hello hello = new Hello();
        hello.getClock().sayTime();
    }
}
于 2014-11-12T19:50:25.173 に答える
7

フィールドは、クラスまたはクラスのインスタンスのいずれかに割り当てることができます。デフォルトでは、フィールドはインスタンス変数です。フィールドを使用staticすると、クラス変数になるため、唯一無二のclock. 1 つの場所を変更すると、どこでも表示されます。インスタンス変数は、互いに独立して変更されます。

于 2009-01-05T17:48:41.860 に答える
6

Java では、staticキーワードは単純に次のことを示すものと見なすことができます。

「特定のインスタンスに関係なく」

このように考えるとstatic、遭遇するさまざまな状況での使用法を理解しやすくなります。

  • フィールドは、特定のstaticインスタンスではなくクラスに属するフィールドです

  • staticメソッドは、の概念を持たないメソッドですthis。クラスで定義されており、参照が渡されない限り、そのクラスの特定のインスタンスについてはわかりません

  • メンバー クラスは、それを囲むクラスのインスタンスの概念や知識を持たないネストされたstaticクラスです (それを囲むクラス インスタンスへの参照が渡されない限り)。

于 2015-10-03T16:15:32.460 に答える
5

static は、クロック メンバーをインスタンス メンバーではなくクラス メンバーにします。static キーワードがなければ、Hello クラスのインスタンス (クロック メンバー変数を持つ) を作成する必要があります。

Hello hello = new Hello();
hello.clock.sayTime();
于 2009-01-05T17:45:58.323 に答える
5

静的メソッドは、それらが定義されているクラスのインスタンス変数を使用しません。違いの非常に良い説明は、このページにあります

于 2009-01-05T17:45:58.947 に答える
5

「ヘルパー」クラスの静的メソッド (可能であればのみ) が好きになりました。

呼び出しクラスは、ヘルパー クラスの別のメンバー (インスタンス) 変数を作成する必要はありません。ヘルパー クラスのメソッドを呼び出すだけです。また、コンストラクターが不要になり、メンバー (インスタンス) 変数が不要になるため、ヘルパー クラスも改善されます。

他にもメリットがありそうですね。

于 2012-12-17T20:34:04.750 に答える
3

「this」ポインターを持たない静的メンバーも考えられます。これらはすべてのインスタンスで共有されます。

于 2009-01-05T19:36:22.890 に答える
1

静的変数 静的メソッドでのみアクセスできるため、静的変数を宣言すると、それらのゲッター メソッドとセッター メソッドは静的メソッドになります。

静的メソッドは、クラス名を使用してアクセスできるクラスレベルです

以下は、静的変数のゲッターとセッターの例です。

public class Static 
{

    private static String owner;
    private static int rent;
    private String car;
    public String getCar() {
        return car;
    }
    public void setCar(String car) {
        this.car = car;
    }
    public static int getRent() {
        return rent;
    }
    public static void setRent(int rent) {
        Static.rent = rent;
    }
    public static String getOwner() {
        return owner;
    }

    public static void setOwner(String owner) {
        Static.owner = owner;
    }

}
于 2015-06-24T16:47:22.107 に答える