![](/img/trans.png)
[英]What´s the difference between AtomicReference<Integer> vs. AtomicInteger?
[英]Difference between Integer, AtomicInteger in java
当我使用 java 的可选 class 时,如下所示
Integer total = null;
Optional<Integer> b = Optional.of(new Integer(10));
b.ifPresent(b -> total =b);
上面的代码不起作用(错误:java:从 lambda 表达式引用的局部变量必须是最终的或有效的最终)但是,当我使用 AtomicInteger 时,它会起作用。 为什么会发生这种情况?
Optional<Integer> b = Optional.of(new Integer(10));
AtomicInteger total = new AtomicInteger();
b.ifPresent(b -> total.set(b));
你可以这样做:
Integer total = Optional.of(new Integer(10)).orElse(null);
如果Optional
值可以为空,那么:
Integer total = Optional.ofNullable(new Integer(10)).orElse(null);
Optional.ofNullable
将在null
值的情况下阻止NPE 。
在第一个示例中出现此错误的原因是在 lambda 表达式中不允许更改局部变量的引用。 这就是为什么它们需要被宣布为final
的或实际上是最终的。
第二个示例之所以有效,是因为在这里您没有更改total
变量的引用。 您只是使用它的set()
方法更新它的值。
AtomicInteger class 通过提供对值执行原子操作的方法来保护底层 int 值。 它不能用作 Integer class 的替代品。
AtomicInteger 的主要用途是当我们处于多线程上下文中时,我们需要在不使用同步关键字的情况下对 int 值执行原子操作。
使用 AtomicInteger 比使用同步执行同样的操作更快、更易读。
在这种情况下,您不仅观察到两个类之间的差异,而且还观察到您使用它们的方式的差异。
b.ifPresent(b -> total =b);
这试图分配一个新的引用,一个对不同Integer
object 的引用,给b
。 Integer
, AtomicInteger
或任何其他类型都不允许这样做。
b.ifPresent(b -> total.set(b));
这将调用现有AtomicInteger
set
中的方法 ( set )。 Integer
、 AtomicInteger
和所有其他类都允许从 lambda 中调用方法。 但是,您的用例的一个重要区别是Integer
没有一种方法可以让您更改值,因为 class 是不可变的。
该怎么做? 请参阅Mushif Ali Nawaz 的好答案。
PS If you want to know more about the difference between the two classes, see this question: What is the difference between Atomic Integer and Normal immutable Integer class in Java?
您问为什么Integer
和AtomicInteger
的行为在您的情况下有所不同。 原因确实与AtomicInteger
无关。 相反,不同之处在于Integer
是不可变的,因此,更改对Integer
的引用值的唯一方法是通过赋值。 但是 lambda 表达式不允许分配给表达式的 scope 之外的局部变量。
有几种方法可以在不使用AtomicInteger
的情况下解决此问题:
MutableInteger
可以在 lambda 中设置Integer
成为 object 变量而不是局部变量orElse
或各种替代方法来返回值,而不是在ifPresent
中设置它另请注意,您可能会考虑OptionalInt
而不是Optional<Integer>
。
他们的行为不同,因为您正在做两件事。
在你的第一个:
b.ifPresent(b -> total =b);
变量“total”表示 memory 中您正在更改其值的区域。 那是不允许的。
在第二:
b.ifPresent(b -> total.set(b));
变量“total”表示 memory 中引用(或指向)class AtomicInteger 实例的区域。 您没有更改该变量,而只是在其上调用方法。 由于“总”本身保持不变,因此被称为“有效最终”,因此是允许的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.