在Java中,我们使用final带变量的关键字来指定其值不被更改.但我发现你可以改变类的构造函数/方法中的值.同样,如果变量是,static那么它是编译错误.
这是代码:
import java.util.ArrayList;
import java.util.List;
class Test {
private final List foo;
public Test()
{
foo = new ArrayList();
foo.add("foo"); // Modification-1
}
public static void main(String[] args)
{
Test t = new Test();
t.foo.add("bar"); // Modification-2
System.out.println("print - " + t.foo);
}
}
Run Code Online (Sandbox Code Playgroud)
上面的代码工作正常,没有错误.
现在将变量更改为static:
private static final List foo;
Run Code Online (Sandbox Code Playgroud)
现在是编译错误.这final真的有用吗?
谁能告诉我这个类是否是线程安全的?
class Foo {
private final Map<String,String> aMap;
public Foo() {
aMap = new HashMap<String, String>();
aMap.put("1", "a");
aMap.put("2", "b");
aMap.put("3", "c");
}
public String get(String key) {
return aMap.get(key);
}
}
Run Code Online (Sandbox Code Playgroud)
编辑:我不能澄清这个问题.根据JMM FAQ:
应提供初始化安全性的新保证.如果一个对象被正确构造(这意味着对它的引用在构造期间不会被转义),那么看到对该对象的引用的所有线程也将看到在构造函数中设置的最终字段的值,而不需要同步.
这让我把这个集合混淆为aMap aMap = new HashMap<String, String>();.所以其他线程可以看到这些
aMap.put("1", "a");
aMap.put("2", "b");
aMap.put("3", "c");
Run Code Online (Sandbox Code Playgroud)
或不 ?
编辑:我发现这个问题与我的问题完全不同