According to the manual, Javassist does not support inner class generation, but claims to support to read and modify them:
- Inner classes or anonymous classes are not supported. Note that this is a limitation of the compiler only. It cannot compile source code including an anonymous-class declaration. Javassist can read and modify a class file of inner/anonymous class.
I guess the compiler support ends where you want to do use inner-class-specific syntactic sugar in source code compiled by Javassist, though. A simple workaround would be to use "sacred knowledge" as follows:
$ javap classes/com/demo/OuterClass$1.class
Compiled from "OuterClass.java"
class com.demo.OuterClass$1 implements java.lang.Runnable {
final com.demo.OuterClass this$0;
com.demo.OuterClass$1(com.demo.OuterClass);
public void run();
}
Oh look, this$0
! Let us try that:
run.setBody("{" +
"System.out.println("staticNum: " + com.demo.OuterClass.staticNum);" +
"System.out.println("instanceNum: " + this$0.instanceNum);" +
"}");
Now we get the console output:
staticNum: 1
instanceNum: 2
I do not know, how stable and reliable this workaround is across Java releases and compiler flavours.
P.S.: If you change the anonymous inner class to a lambda, the class file looks completely different and you are lost again. I found nothing in the Javassist repository even mentioning lambdas, only a few open issues reporting problems.
Update: I created Javassist issue #358 in order to track this.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…