Question

com.sun.jdi is a package that lets you get information about a running VM, add breakpoints, look through stack frames, etc.

How can I get the enclosing instance of another instance? For example, here is some code that creates 4 instances of the inner class Garfield.Lasagna, with two each being enclosed by a different instance of 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();
 }
}

I would imagine that com.sun.jdi.ObjectReference would have a way to get at the instance enclosing an instance, but it doesn't seem to be the case.

Or, I would try to use reflection in the debugged VM, something like java.lang.Class.getEnclosing{Class,Constructor,Method}() but I don't see any related method that applies to objects/instances.

Was it helpful?

Solution

You can both access it through the JDI and through reflection. The enclosing instance is stored as a field of instances of the inner class Lasanga. The automatically-generated name for the field is usually this$0 (so in the example above, the field with this name has type Garfield).

To access it in the JDI, you have to use the ReferenceType of the ObjectReference. There are three relevant methods of ReferenceType:

  • fields() gives you all simple fields and also these synthetic fields
  • visibleFields() additionally gives you inherited fields
  • allFields() additionally gives you hidden fields (and possibly repeats synthetic fields)

Accessing it through reflection is the same as usual, just ask for the field of name "this$0".

But, you can't access the synthetically-defined variable at compile time, asking for the field this$0 will cause a compile-time error.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top