在阅读HashMap
的源代码时,我在public V put(K key, V value)
中看到了这个代码段:
for (Entry<K,V> e = table[i]; e != null; e = e.next) {
Object k;
if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
V oldValue = e.value;
e.value = value;
e.recordAccess(this);
return oldValue;
}
}
为什么要将e.key
分配给k
进行比较?为什么不直接比较,如:
if (e.hash == hash && (e.key == key || key.equals(e.key))
-------------------更新------------------------
根据@seand的回答,我做了更详细的调查:
import com.test.Test;
public class Main {
public static void main(String[] args) {
Test t = new Test();
int a = t.a;
int b = a;
}
}
类测试有一个int提交a;
使用javap -c Main获取类文件内容:
public static void main(java.lang.String[]);
Code:
0: new #2 // class test/Test
3: dup
4: invokespecial #3 // Method test/Test."<init>":()V
7: astore_1
8: aload_1
9: getfield #4 // Field test/Test.a:I
12: istore_2
13: iload_2
14: istore_3
15: return
int a = t.a
代表
8:[load the t object]
9:[access the field a]
12:[store the value to a]
请参阅jvm specification获取[getfield]
的信息 int b = a
代表:
13:[load the local variable]
14:[store the value to b];
访问局部变量似乎比使用类字段更合理。
答案 0 :(得分:4)
我猜这是一个优化,可以为e.key节省额外的查询。 (虽然它实际上不是使用invokevirtual的方法调用,但它可以节省一个间接级别)。由于这是一个使用非常频繁的库函数,作者可能会使用他们可以想到的每个技巧来获得最佳性能。您还可以在k = e.key
中查看它如何检查对象标识,这可以避免稍微昂贵的equals()
电话。