web-dev-qa-db-ja.com

素人の用語では、Javaで「静的」とはどういう意味ですか?

ウィキペディアで調べていくつかの定義を聞いてきましたが、Javaの初心者として、それが何を意味するのかまだわかりません。 Javaとばかに流Anyな人はいますか?

94
Philip Strong

staticは、そのようにマークされた変数またはメソッドがクラスレベルで利用可能であることを意味します。つまり、アクセスするためにクラスのインスタンスを作成する必要はありません。

public class Foo {
    public static void doStuff(){
        // does stuff
    }
}

したがって、Fooのインスタンスを作成してから、次のようにdoStuffを呼び出す代わりに:

Foo f = new Foo();
f.doStuff();

次のように、クラスに対して直接メソッドを呼び出すだけです。

Foo.doStuff();
237
inkedmn

非常に素人の用語では、クラスは型であり、オブジェクトはその型で作成されたコピーです。静的は型に属し、コピーを作成せずに直接アクセスできるため、上記の例

37
Bostone

StaticキーワードはJavaでいくつかの異なる方法で使用でき、ほとんどすべての場合、それは変更するものがオブジェクトインスタンスを囲むことなく使用できることを意味する修飾子です

Javaはオブジェクト指向言語であり、デフォルトで記述するほとんどのコードは、使用するオブジェクトのインスタンスを必要とします。

public class SomeObject {
    public int someField;
    public void someMethod() { };
    public Class SomeInnerClass { };
}

SomeField、someMethod、またはSomeInnerClassを使用するには、まずSomeObjectのインスタンスを作成する必要があります。

public class SomeOtherObject {
    public void doSomeStuff() {
        SomeObject anInstance = new SomeObject();
        anInstance.someField = 7;
        anInstance.someMethod();
        //Non-static inner classes are usually not created outside of the
        //class instance so you don't normally see this syntax
        SomeInnerClass blah = anInstance.new SomeInnerClass();
    }
}

それらを静的と宣言した場合、それらはを囲むインスタンスを必要としません

public class SomeObjectWithStaticStuff {
    public static int someField;
    public static void someMethod() { };
    public static Class SomeInnerClass { };
}

public class SomeOtherObject {
    public void doSomeStuff() {
        SomeObjectWithStaticStuff.someField = 7;
        SomeObjectWithStaticStuff.someMethod();
        SomeObjectWithStaticStuff.SomeInnerClass blah = new SomeObjectWithStaticStuff.SomeInnerClass();
        //Or you can also do this if your imports are correct
        SomeInnerClass blah2 = new SomeInnerClass();
    }
}

静的なものを宣言すると、いくつかの意味があります。

まず、アプリケーション全体で静的フィールドの値は1つしかありません

public class SomeOtherObject {
    public void doSomeStuff() {
        //Two objects, two different values
        SomeObject instanceOne = new SomeObject();
        SomeObject instanceTwo = new SomeObject();
        instanceOne.someField = 7;
        instanceTwo.someField = 10;
        //Static object, only ever one value
        SomeObjectWithStaticStuff.someField = 7;
        SomeObjectWithStaticStuff.someField = 10; //Redefines the above set
    }
}

2番目の問題は、静的メソッドと内部クラスが囲んでいるオブジェクトのフィールドにアクセスできないことです(ないため)。

public class SomeObjectWithStaticStuff {
    private int nonStaticField;
    private void nonStaticMethod() { };

    public static void someStaticMethod() {
        nonStaticField = 7; //Not allowed
        this.nonStaticField = 7; //Not allowed, can never use *this* in static
        nonStaticMethod(); //Not allowed
        super.someSuperMethod(); //Not allowed, can never use *super* in static
    }

    public static class SomeStaticInnerClass {

        public void doStuff() {
            someStaticField = 7; //Not allowed
            nonStaticMethod(); //Not allowed
            someStaticMethod(); //This is ok
        }

    }
}

Staticキーワードは、内部インターフェイス、注釈、および列挙にも適用できます。

public class SomeObject {
    public static interface SomeInterface { };
    public static @interface SomeAnnotation { };
    public static enum SomeEnum { };
}

これらのすべての場合において、キーワードは冗長であり、効果はありません。インターフェイス、注釈、および列挙型は、内部クラスとの関係を持たないため、デフォルトでは静的です。

これは、彼らのキーワードが何をするかを説明するだけです。キーワードの使用が悪い考えであるかどうかについては説明しません。 多くの静的メソッドを使用しているのは悪いことですか? などの他の質問でさらに詳しく説明できます。

キーワードstaticのあまり一般的ではない使用法もいくつかあります。修飾されていない静的型(冗長に静的にマークされていないインターフェイス、注釈、列挙型を含む)を使用できる静的インポートがあります。

//SomeStaticThing.Java
public class SomeStaticThing {
    public static int StaticCounterOne = 0;
}

//SomeOtherStaticThing.Java
public class SomeOtherStaticThing {
    public static int StaticCounterTwo = 0;
}

//SomeOtherClass.Java
import static some.package.SomeStaticThing.*;
import some.package.SomeOtherStaticThing.*;

public class SomeOtherClass {
    public void doStuff() {
        StaticCounterOne++; //Ok
        StaticCounterTwo++; //Not ok
        SomeOtherStaticThing.StaticCounterTwo++; //Ok
    }
}

最後に、クラスが最初にロードされたときに実行されるコードのブロックである静的イニシャライザがあります(通常、アプリケーションでクラスが初めてインスタンス化される直前に)および(静的メソッドのように)非静的フィールドまたはメソッドにアクセスできません。

public class SomeObject {

    private static int x;

    static {
        x = 7;
    }
}
15
Pace

静的属性の場合の別の優れた例およびシングルトン設計パターンを適用する場合に操作が使用されます。一言で言えば、Singleton設計パターンは、システムの存続期間中に特定のクラスのオブジェクトを1つだけ構築することを保証します。 1つのオブジェクトのみが構築されることを保証するために、シングルトンパターンの典型的な実装は、許可された単一のオブジェクトインスタンスへの内部静的参照を保持し、そのインスタンスへのアクセスはstatic操作を使用して制御されます

7
mel3kings

@inkedmnが指摘したことに加えて、静的メンバーはクラスレベルにあります。したがって、そのメンバーは、そのクラスに対して1回JVMによってメモリにロードされます(クラスがロードされるとき)。つまり、nが所属するクラスのインスタンスnにロードされる静的メンバーのインスタンスはありません。

3
wulfgarpro