gpt4 book ai didi

java - 为什么 Java API 在 if 语句中有看似奇怪的赋值?

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:59:44 26 4
gpt4 key购买 nike

我是编程和 Java 的新手。我注意到,在 Java API 中,有些方法在 if 语句中有奇怪的赋值。

这是 map 界面的一个例子:

default V replace(K key, V value) {
V curValue;
if (((curValue = get(key)) != null) || containsKey(key)) {
curValue = put(key, value);
}
return curValue;
}

以这种方式嵌套赋值有什么好处吗?这纯粹是一种风格选择吗?为什么不在 curValue 首次声明时才进行赋值?

// why not do it like this?
default V replace(K key, V value) {
V curValue = get(key); // not nested
if (curValue != null || containsKey(key)) {
curValue = put(key, value);
}
return curValue;
}

我在 Map 接口(interface)和其他地方的许多新添加的 Java 8 方法中注意到了这一点。这种嵌套赋值的形式似乎没有必要。

编辑: map 界面的另一个例子:

default V computeIfAbsent(K key,
Function<? super K, ? extends V> mappingFunction) {
Objects.requireNonNull(mappingFunction);
V v;
if ((v = get(key)) == null) {
V newValue;
if ((newValue = mappingFunction.apply(key)) != null) {
put(key, newValue);
return newValue;
}
}

return v;
}

最佳答案

这实际上是在复制到一个局部变量,这会产生更小的字节码,它被视为一种绝对极端的优化方式,您将在 jdk 代码的许多其他地方看到这一点。

另一件事是,多次读取一个局部变量意味着只读取一次共享变量,例如,如果它是一个 volatile 并且你只读取它一次并使用它方法内。

编辑

这两种方法的区别在于单次读取尽我所能

假设我们有这两种方法:

V replace(K key, V value) {
V curValue;
if ((curValue = map.get(key)) != null || map.containsKey(key)) {
curValue = map.put(key, value);
}
return curValue;
}

V replaceSecond(K key, V value) {
V curValue = map.get(key); // write
if (curValue != null || map.containsKey(key)) { // read
curValue = map.put(key, value); // write
}
return curValue;
}

此字节码几乎相同,除了:replaceSecond 将具有:

 astore_3 // V curValue = map.get(key); store to curValue
aload_3 // curValue != null; read the value from curValue

虽然 replace 方法将是:

 dup      // duplicate whatever value came from map.get(key)
astore_3 // store the value, thus "consuming" it form the stack

在我看来,dup 不算是另一次阅读,所以我猜这就是所谓的极端优化

关于java - 为什么 Java API 在 if 语句中有看似奇怪的赋值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48654075/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com