你如何获得实例的封闭实例? (com.sun.jdi)

时间:2013-05-20 00:29:15

标签: java inner-classes jdi

com.sun.jdi是一个软件包,可让您获取有关正在运行的VM的信息,添加断点,查看堆栈帧等。

如何获取另一个实例的封闭实例?例如,下面是一些代码,用于创建内部类Garfield.Lasagna的4个实例,其中两个实例由Garfield的不同实例包围。

public class Garfield {
 int belly;
 public class Lasagna {
    Lasagna() {belly++;}
 }
 public static void main(String[] args) {
    Garfield g1 = new Garfield();
    Lasagna l11 = g1.new Lasagna();
    Lasagna l12 = g1.new Lasagna();
    Garfield g2 = new Garfield();
    Lasagna l21 = g2.new Lasagna();
    Lasagna l22 = g2.new Lasagna();
 }
}

我认为com.sun.jdi.ObjectReference有办法获取包含实例的实例,但似乎并非如此。

或者,我会尝试在调试的VM中使用反射,例如java.lang.Class.getEnclosing{Class,Constructor,Method}(),但我没有看到任何适用于对象/实例的相关方法。

1 个答案:

答案 0 :(得分:1)

您可以通过JDI和反射访问它。封闭实例存储为内部类Lasanga的实例字段。字段的自动生成名称通常为this$0(因此在上面的示例中,具有此名称的字段的类型为Garfield)。

要在JDI中访问它,您必须使用ObjectReference的ReferenceType。有three relevant methods of ReferenceType

  • fields()为您提供所有简单字段以及这些合成字段
  • visibleFields()还为您提供了继承的字段
  • allFields()还为您提供隐藏字段(并可能重复合成字段)

通过反射访问它与通常一样,只需要询问名称"this$0"的字段。

但是,您无法在编译时访问合成定义的变量,要求字段this$0将导致编译时错误。