相关疑难解决方法(0)

Java中的"final"关键字如何工作?(我仍然可以修改一个对象.)

在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真的有用吗?

java final

457
推荐指数
9
解决办法
45万
查看次数

79
推荐指数
2
解决办法
2万
查看次数

性能ConcurrentHashmap vs HashMap

如何将ConcurrentHashMap的性能与HashMap进行比较,特别是.get()操作(我特别感兴趣的是只有少数几个项目的情况,范围可能在0-5000之间)?

有没有理由不使用ConcurrentHashMap而不是HashMap?

(我知道不允许使用空值)

更新

只是为了澄清,显然在实际并发访问的情况下性能会受到影响,但是如何在没有并发访问的情况下比较性能呢?

java collections hashmap

63
推荐指数
2
解决办法
5万
查看次数

不可变物体是否可以不受不当出版的影响?

这是来自JCiP的示例。

public class Unsafe {
    // Unsafe publication 
    public Holder holder;

    public void initialize() {
        holder = new Holder(42);
    }
}

public class Holder {
    private int n;

    public Holder(int n) {
        this.n = n;
    }
    public void assertSanity() {
        if (n != n) {
            throw new AssertionError("This statement is false.");
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

在第34页上:

[15]这里的问题不是Holder类本身,而是Holder没有正确发布。但是,可以通过将n字段声明为final来使Holder免受不适当发布的影响,这将使Holder不变。

这个答案

final的规范(请参阅@andersoj的答案)保证当构造函数返回时,将对final字段进行适当的初始化(从所有线程可见)。

维基

例如,在Java中,如果已经内联了对构造函数的调用,则一旦分配了存储空间,但是在内联的构造函数初始化对象之前,可以立即更新共享变量。

我的问题是:

因为:(可能不正确,我不知道。)

a)可以在内联构造函数初始化对象之前立即更新共享变量。

b)只有在构造函数返回时,才能保证对final字段进行正确的初始化(从所有线程可见)。

另一个线程是否可能看到默认值holder.n?(即,另一个线程holderholder构造函数返回之前获得对它的引用。)

如果是这样,那么您如何解释以下声明?

通过将n字段声明为final,可以使Holder免受不适当发布的影响,这将使Holder不可变

编辑: …

java multithreading publish immutability

2
推荐指数
1
解决办法
318
查看次数