首页 > 解决方案 > IntelliJ:逐步调试新的 HashSet():字段在没有看到的情况下被初始化

问题描述

我不知道问题是我的 JDK 版本、我的 IntelliJ 版本还是由于对 Java 缺乏完整的理解造成的。
我正在检查HashSet实现,我想知道该字段何时keySet初始化。我看到了方法

public Set<K> keySet() {
    Set<K> ks = keySet;
    if (ks == null) {
        ks = new KeySet();
        keySet = ks;
    }
    return ks;
}

这似乎是第一次设置字段的地方,但是当我将断点设置为条件时,ks它永远不会为空!所以我决定检查它是在什么时候初始化的,但我似乎没有找到它。我只是使用 IntelliJ 的Force Step Into按钮逐步运行以下指令 (1) :

HashSet<String> set = new HashSet<>();

我得到指令(2):

map = new HashMap<>();

并按照说明 (3)

 this.loadFactor = DEFAULT_LOAD_FACTOR;

在指令 (3) 之后,就在离开构造函数之前public HashMap(),如果我评估该字段keySet,它仍然为空。
但是在那之后,就在指令(2)之后,在离开构造函数之前public HashSet(),如果我评估map.keySet它不再为空!

这是什么魔法?我在这里遗漏了什么还是我的调试器有问题?我正在使用 jdk-9.0.1 和 IntelliJ IDEA 2017.2.5

标签: javadebuggingintellij-ideahashset

解决方案


当你调试的时候,调试器会尝试向你展示 的内容HashSet,所以它调用了 setstoString()方法,它间接调用keySet()了 backing HashMapobject 的方法,从而初始化了keySet字段。

调试器在调用 时会忽略断点toString(),因此您看不到调用。


推荐阅读