3

静的/クラス変数は型/クラスで定義され、それが定義されている型/クラスに関連付けられ、型/クラスのインスタンスから独立していると言われます。タイプ/クラスには静的/クラス変数が1つだけあり、定数のようなプロパティに最適です。その値は、クラスのすべてのインスタンス間で共通です。静的/クラス変数の状態は常にクラスに存在するため、クラスには常に1つの変数しかなく、キーワードstaticを使用して変数のこの性質を定義します。ベストプラクティスの静的/クラス変数は一度初期化する必要があり、これはキーワードfinalを使用して保証されます。最後の静的変数は、new String()またはnew Integer()のように、不変のコレクションで初期化されます。

今私の質問は、静的変数からの値がどのように使用されるかです。そして、この変数の使用法は何と呼ばれていますか?たとえば、含まれているクラスからその値をコピーしますか、それともクラス内の変数への明示的な参照ですか?

例えば

class GenericType {
    private final static String commonValue = new String("foobar");
} 
class AnotherGenericType {
    public static void main(String[] args) {
        System.out.println(GenericType.commonValue); //Displays foobar in the console.

    }
}
4

4 に答える 4

5

static変数の格納用に特別に割り当てられたスペースがあります。これは、JLS8.3.1.1で指定されています。

フィールドが静的であると宣言された場合、クラスのインスタンスがいくつ(場合によってはゼロ)作成されても、フィールドのインカネーションは1つだけ存在します。クラス変数と呼ばれることもある静的フィールドは、クラスが初期化されるときに具体化されます。

これらの変数は、クラスがアンロードされるまで(通常は頻繁に発生しません)、収集されたガベージに対して開かれないことに注意してください。これは、意図しないメモリ参照が保持される可能性があります。

静的メンバーへのアクセスは、「静的アクセス」と呼ばれることもありますが(以前に使用されたと聞いています)、通常、独自の用語はありません。

于 2012-07-25T18:21:51.007 に答える
1

静的変数は、クラスのインスタンス間ではなく、クラス自体に関連付けられます。キーワードでマークされたものstaticはすべて、実行時にクラスがロードされるときに初期化されます。これが、クラス名でそれらを呼び出すことができる理由であり、オブジェクトを作成せずにそれらを使用できる理由です。

JLSは、静的変数の使用が呼び出されることを指定していますusing a static variable。冗談だ。

于 2012-07-25T18:21:19.160 に答える
1

これは単なる参照です。

この場合、としてcommonValue定義されfinalString不変であるため、それを見ることができません。ただし、次のコードがあるとします。

public class GenericType {
    public static Collection myCollection = new ArrayList();
}

public class Test {

    public static void main(String[] args) {
        // you are accessing the public static field
        GenericType.myCollection.add("first item");
        System.out.println(GenericType.myCollection);

        // now c holds a reference for the collection that is referred by myCollection field
        Collection c = GenericType.myCollection;
        GenericType.myCollection.add("second item");
        GenericType.myCollection = new ArrayList();

        // printing the object referred by c (the old reference hold by myCollection field)
        System.out.println(c);

        // and here the current reference of myCollection field
        System.out.println(GenericType.myCollection);
    }

}
于 2012-07-25T18:24:30.850 に答える
0

@Francisco Spaethが指摘しているように、JLSは明確です。インスタンス間で共有される静的な値は1つだけです。
ただし、クラスは異なるclassLoaderを使用して同じプログラムにロードできます。つまり、classLoaderごとに異なる静的値を持つ可能性があります。例として:

package classloaders;

import java.lang.reflect.Field;
import java.net.URL;
import java.net.URLClassLoader;

class SampleClass{
    static public final long loadTime = System.nanoTime();
}

public class Main {

    public static void main(String[] args) throws Exception {

        URL url = new URL("file:///C:/workspaces/personal/JavaTest/bin/");
        ClassLoader cl1 = new URLClassLoader(new URL[]{url}, null);
        ClassLoader cl2 = new URLClassLoader(new URL[]{url}, null);

        Class<SampleClass> sampleClass = (Class<SampleClass>) cl1.loadClass("classloaders.SampleClass");
        Field field1 = sampleClass.getField("loadTime");
        field1.setAccessible(true);
        System.out.println(field1.get(null));

        Class<SampleClass> sampleClass2 = (Class<SampleClass>) cl2.loadClass("classloaders.SampleClass");
        Field field2 = sampleClass2.getField("loadTime");
        field2.setAccessible(true);
        System.out.println(field2.get(null));

    }

}

このコードを実行すると、次のようになります

193798032450350
193798062432257

したがって、異なるクラスローダーを使用することにより、同じクラスの同じ静的フィールドに2つの異なる値を表示できます。

しかし、それは非常に奇妙なケースです...

于 2012-07-25T19:23:43.397 に答える