编辑:The ticket I've linked in this answer 已被标记为已验证/已修复。它已集成到最新的 Oxygen 版本中,as detailed in the release notes。我将在下面留下我原来的答案,因为它有很多关于 JDI 和 JDT 如何在 Eclipse 中协同工作的有用信息。
我将从您问题的最终答案开始,因此如果您不想阅读详细信息,则无需阅读。基本上,这是可能的,但有很多问题需要首先回答。如果你想跳过那个直接去买票,here you go,但我建议你继续阅读。
Eclipse 使用JDI(该页面的最底部)向 JVM 注册观察点。这是通过创建观察点的EventRequestManager 方法(实现由JVM 本身提供,而不是Eclipse)完成的,即EventRequstManager.createModificationWatchpointRequest。这些方法唯一接受的是Field(请注意,这不是反射Field 类)。所以简而言之,Eclipse不能直接通过Java来做。不用担心,Java 也不处理条件断点。这些也是通过 Eclipse 直接实现的,而不是依赖于 Java。然而,有一些注意事项使得条件观察点比条件断点更难实现。
让我们考虑简单的条件断点。为了让它们工作,您需要一个可以在其中执行代码 sn-p 的上下文。如果没有代码的执行上下文,我们无法评估 sn-p 中的表达式/语句,因为我们无法解析变量、值、类型等。这是使用处理 Java 的 AST 解析器完成的代码转化为实际指令。请记住,您可以在条件中键入多个语句,而不仅仅是单个表达式。然后,求值器在解析表达式后使用上下文(特别是 IJavaStackFrame)对表达式本身求值。
现在考虑一个条件观察点,因为最后一点非常重要。什么是观察点的执行上下文?变量访问不仅可以发生在同一个类中,还可以发生在其他类中(想想protected 和包成员),也可以发生在内部类中(通过MyClass.this.myField)。这意味着:
- 局部变量永远不会一致,因为可以通过多种方法访问该字段,
- 调用访问的类的成员变量永远不会一致,因为可以从多个类访问该字段,
- 由于与 (2) 相同的原因,在执行上下文中可用的导入类永远不会一致,并且
- 字段本身的访问永远不会一致,因为它可能需要使用实例、类名、
super 或 MyClass.this.myField 之类的东西(用于内部类访问)进行限定。
这种功能的可行性是有限的。您将很难实际评估观察点的不变条件语句,因为执行上下文中绝对没有任何内容是一致的。这意味着如果没有对代码段应用特殊含义,则代码无法轻松解析和解释,例如:
myField 始终与 this.myField 或 super.myField 或 MyClass.myField 或 MyClass.this.myField 相同,具体取决于访问字段的位置。
这使事情变得相当复杂,尤其是在一个已经相对复杂的系统中。条件断点代码的示例可以在here 中找到(使用Ctrl+F 搜索getEvaluationEngine)。现在接受它并根据一组关于我们在哪里和字段在哪里的规则对表达式添加预处理,并且做事情会变得复杂。
AFAIK,你不能做类似“如果旧/新值是这个,暂停”之类的事情,因为这些信息根本无法从堆栈帧中获得的信息中获得(因此来自调试器)。分配给该值的表达式已按观察点被命中的时间进行评估,但其结果对调试器不可用,因此它对观察点本身的评估器不可用。必须首先执行一个步骤来执行分配,然后必须在该步骤之后评估表达式。这将是非常混乱的,老实说,相当老实。
无论如何,如果您想表达对此功能的支持,您可以使用this Eclipse ticket。然而,它自 2005 年以来(截至目前 8 年)就已经存在,并且社区的支持有限。 TBH,我认为它不会走得太远,尤其是没有更多地澄清这种功能请求背后的期望,也没有首先考虑一些主要的设计考虑。