Мне трудно использовать сгенерированный класс байт-кода, который загружается Unsafe.defineAnonymousClass()
. Мне интересно, как использовать объект анонимного класса для инициализации другого класса (или анонимного класса).
Возьмем пример класса Callee ниже, например, его конструктор принимает Callee2 в качестве параметра.
Class Callee{
Callee2 _call2;
public Callee(Callee2 callee2){
...
}
}
Во время выполнения я создал новые классы для Callee2 и Callee, и оба новых класса загружаются Unsafe.defineAnonymousClass()
. Для нового Callee конструктор также изменяется на:
public test.code.jit.asm.simple.Callee(test.code.jit.asm.simple.Callee2.1506553666);
flags: ACC_PUBLIC
Code:
stack=2, locals=3, args_size=2
0: aload_0
1: invokespecial #65 // Method java/lang/Object."<init>":()V
....
8: return
в то время как сгенерированное имя класса Callee2:
class test.code.jit.asm.simple.Callee2/1506553666
Я создал экземпляр Callee2/1506553666 и хочу создать с ним экземпляр нового Callee, но не могу:
newCls.getConstructor(args).newInstance(objs);
где args = [class test.code.jit.asm.simple.Callee2/1506553666]
и objs= [test.code.jit.asm.simple.Callee2/1506553666@39b0a038]
args[0] не имеет смысла, так как этот класс загружается анонимным загрузчиком (на анонимные классы не ссылаются никакие загрузчики классов). Так что меня действительно озадачивает, как передать объекты в массиве objs вызову метода.
Исключение возникает при вызове getConstructor (args) с сообщением:
java.lang.NoClassDefFoundError: test/code/jit/asm/simple/Callee2/1506553666
at java.lang.Class.getDeclaredConstructors0(Native Method)
at java.lang.Class.privateGetDeclaredConstructors(Class.java:2483)
at java.lang.Class.getConstructor0(Class.java:2793)
at java.lang.Class.getConstructor(Class.java:1708)
at code.jit.asm.util.ReflectionUtil.adapt2GeneratedObject(ReflectionUtil.java:36)
at code.jit.asm.services.BytecodeGenerator.generator(BytecodeGenerator.java:164)
Исключение явно для меня, поскольку анонимный класс является временным для любого загрузчика классов. Но в моем случае мне нужно инициализировать новый Callee (также анонимный класс) новым экземпляром Callee2 (байт-коды в конструкторе Callee будут считывать члены поля Callee2), так что есть ли обходной путь для передачи нового экземпляра callee2 для нового вызываемого конструктора?
Callee2
был неправильно введен в загрузчик классов. Вот почему он не может загрузить классCalle2
. Однажды (давным-давно) я сгенерировал динамический код, скомпилировал его с помощью инструментов компилятора и внедрил, но выбрал другой подход. Подробнее см. здесь. - person fps   schedule 11.07.2015