8

知られているように、オブジェクト参照があり、この参照に最終フィールドがある場合、最終フィールドから到達可能なすべてのフィールドが表示されます(少なくともコンストラクターが終了したとき)

例 1:

class Foo{
    private final Map map;
     Foo(){
         map = new HashMap();
         map.put(1,"object");
     }

     public void bar(){
       System.out.println(map.get(1));
     }
}

この場合、次の理由により、メソッドが常に出力されることが保証されていますbar()。1 .クラスの完全なコードをリストし、マップは最終です。2. 一部のスレッドが参照を参照し、この参照が != null である場合、最終参照値から到達可能であることが保証されます。object
Foo
Foomap

私もそう思います

例 2:

class Foo {
    private final Map map;
    private Map nonFinalMap;

    Foo() {
        nonFinalMap = new HashMap();
        nonFinalMap.put(2, "ololo");
        map = new HashMap();
        map.put(1, "object");
    }

    public void bar() {
        System.out.println(map.get(1));
    }

    public void bar2() {
        System.out.println(nonFinalMap.get(2));
    }
}

bar()ここでは、メソッドについて同じ保証がありますが、割り当ての前に割り当てが発生してもbar2スローでき ます。NullPointerExceptionnonFinalMapmap

揮発性について知りたい:

例 3:

class Foo{
        private volatile Map map;
         Foo(){
             map = new HashMap();
             map.put(1,"object");
         }

         public void bar(){
           System.out.println(map.get(1));
         }
    }

私が理解しているように、bar()メソッドはスローできませんNullPoinerExceptionが、印刷できますnull。(私はこの点について完全に確信が持てません)

例 4:

class Foo {
    private volatile Map map;
    private Map nonVolatileMap;

    Foo() {
        nonVolatileMap= new HashMap();
        nonVolatileMap.put(2, "ololo");
        map = new HashMap();
        map.put(1, "object");
    }

    public void bar() {
        System.out.println(map.get(1));
    }

    public void bar2() {
        System.out.println(nonFinalMap.get(2));
    }
}

ここでは、割り当てがより高い揮発性のマップ割り当てを記述したため、bar()メソッドもbar2()スローできないという同じ保証があると思いますが、nullを出力できますNullPointerExceptionnonVolatileMap


エリオット・フリッシュのコメントの後に追加

レースの例による出版:

public class Main {
    private static Foo foo;

    public static void main(String[] args) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                foo = new Foo();
            }
        }).start();


        new Thread(new Runnable() {
            @Override
            public void run() {
                while (foo == null) ; // empty loop

                foo.bar();
            }
        }).start();

    }
}

コード スニペットに対する私のコメントを証明または修正してください。

4

1 に答える 1