为什么不直接比较e.key而不是将其分配给变量?

时间:2013-12-06 04:34:50

标签: java hashmap

在阅读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];

访问局部变量似乎比使用类字段更合理。

1 个答案:

答案 0 :(得分:4)

我猜这是一个优化,可以为e.key节省额外的查询。 (虽然它实际上不是使用invokevirtual的方法调用,但它可以节省一个间接级别)。由于这是一个使用非常频繁的库函数,作者可能会使用他们可以想到的每个技巧来获得最佳性能。您还可以在k = e.key中查看它如何检查对象标识,这可以避免稍微昂贵的equals()电话。