Java:最终字段冻结从最终字段可访问的对象

前端之家收集整理的这篇文章主要介绍了Java:最终字段冻结从最终字段可访问的对象前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
题为“ Core Java Concurrency”的DZone refcard指出:

Once set,final field values
cannot be changed. Marking an object reference field as final does
not prevent objects referenced from that field from changing later. For
example,a final ArrayList field cannot be changed to a different
ArrayList,but objects may be added or removed on the list instance.

Final field freeze includes not just the final fields in the object but also all
objects reachable from those final fields.

我不完全清楚第二个声明.这是否意味着如果我在类B类的A类中有一个最后一个字段,而后者又有一个类型为Integer的最终字段,则只有在bc的最终字段冻结已经发生了什么?

public class A{

  public final B b = new B();

}

public class B{ 

  public final Integer c = 10;

}

解决方法

Does this mean that if I have a final
field in class A of type Class B,
which in turn have a final field of
type Integer,then final field freeze
for an instance of class A completes
only after the final field freeze for
b.c have already happened?

我想我会仔细地说,在这种情况下,最终的字段冻结意味着当你创建一个A的实例并安全地发布它,其他对象永远不会看到b或c的未初始化的值.

我也会说,当你在A中创建B的实例时,A中的其他初始化代码将永远不会看到c的未初始化值.

一个遇到真正问题的例子是例如一个包含一个(可变的)HashMap的类,只用于在构建过程中初始化:

public class DaysOfWeek {
    private final Map daysOfWeek = new HashMap();
    public DaysOfWeek() { 
      // prepopulate my map
      daysOfWeek.put(0,"Sunday");
      daysOfWeek.put(1,"Monday");
      // etc
    }

    public String getDayName(int dayOfWeek) {
      return daysOfWeek(dayOfWeek);
    }
}

问题出在这里:假设这个对象被安全地发布,并且由于这里没有同步,其他线程调用getDayName()是否安全?答案是肯定的,因为最终的域冻结保证HashMap和一切都可以从它(这里只是字符串,但可以是任意复杂的对象)可以到达结构冻结. [如果你想在构建之后实际修改这个地图,那么你需要在读写上进行明确的同步.]这是一个lengthier blog探索这个主题,并检查一些有趣的回应的意见,像Brian Goetz这样的人.

btw我是refcard的作者

原文链接:https://www.f2er.com/java/123994.html

猜你在找的Java相关文章