昨天有朋友問我,IDEA調(diào)式HashMap,在調(diào)式下面代碼的時候,entrySet一開始就有值了,但是沒有找到給entrySet賦值的地方。
public Set<Map.Entry<K,V>> entrySet() {
Set<Map.Entry<K,V>> es;
return (es = entrySet) == null ? (entrySet = new EntrySet()) : es;
}
我寫了段代碼驗證,發(fā)現(xiàn)確實如此,開始我以為是jdk1.8的原因,相同代碼放到1.6后還是如此。
public class HashMapEntrySetTest {
public static void main(String[] args) {
Map<String, String> map = new HashMap<>();
map.put("aaa","aaaa");
map.entrySet();
}
}
調(diào)式結(jié)果:

IDEA調(diào)式
我在https://blog.csdn.net/lwj_zeal/article/details/72899934找到了答案,IDEA在調(diào)式的時候會調(diào)用對象的toString方法。驗證代碼如下:
public class DebugTest {
@Override
public String toString() {
System.out.println("======debug======");
return super.toString();
}
public static void main(String[] args) {
System.out.println("======start======");
DebugTest debugTest = new DebugTest();
}
}
不加debug輸出結(jié)果是:======start======
在System.out.println("======start======");行加斷點,單步執(zhí)行時會多輸出======debug======。也就是說IDEA在單步執(zhí)行時會調(diào)用對象的toString方法。
現(xiàn)在再來看HashMap的toString方法,HashMap沒有重寫toString,而是在它的父類AbstractMap重寫了。
public String toString() {
Iterator<Entry<K,V>> i = entrySet().iterator();
if (! i.hasNext())
return "{}";
StringBuilder sb = new StringBuilder();
sb.append('{');
for (;;) {
Entry<K,V> e = i.next();
K key = e.getKey();
V value = e.getValue();
sb.append(key == this ? "(this Map)" : key);
sb.append('=');
sb.append(value == this ? "(this Map)" : value);
if (! i.hasNext())
return sb.append('}').toString();
sb.append(',').append(' ');
}
}
從上面代碼可以看到,在toString中有調(diào)用entrySet()方法,entrySet第一次賦值是在這里。
為了再次確認是IDEA的問題,我又在eclipse中調(diào)式entrySet方法,發(fā)現(xiàn)第一次進去的時候是為空。

eclipse調(diào)式