Я пишу приложение, которое требует динамической реализации интерфейса. У меня не было (очевидных) проблем в отношении создания класса: я проверил его как с javap, так и с декомпилятором.Внедрить интерфейс с ASM: ClassCastException
Проблема заключается в том, что после создания класса я определяю и создаю экземпляр. Наконец, я применил его к типу реализованного интерфейса.
Проблема в том, что меня поражают java.lang.ClassCastException: MyGeneratedClass cannot be cast to MyInterface
, хотя я добавляю MyInterface
в качестве интерфейса, когда я звоню ClassWriter.visit
.
Ниже приведен SSCCE, демонстрирующий проблему для интерфейса с именем MyInterface
, полным методов void.
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
cw.visit(V1_6,
ACC_PUBLIC | ACC_SUPER,
"MyGeneratedClass",
null,
"java/lang/Object",
new String[]{MyInterface.class.getName().replace(".", "/"});
{
MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
mv.visitVarInsn(ALOAD, 0);
mv.visitMethodInsn(INVOKESPECIAL,
"java/lang/Object",
"<init>",
"()V");
mv.visitInsn(RETURN);
mv.visitMaxs(0, 0);
mv.visitEnd();
}
for (Method call : MyInterface.class.getDeclaredMethods()) {
MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, call.getName(), Type.getMethodDescriptor(call), null, null);
// ...
mv.visitInsn(RETURN);
mv.visitMaxs(0, 0);
mv.visitEnd();
}
cw.visitEnd();
byte[] raw = cw.toByteArray();
try {
return (MyInterface) new ClassLoader() {
public Class defineClass(byte[] bytes) {
return super.defineClass("MyGeneratedClass", bytes, 0, bytes.length);
}
}.defineClass(raw).newInstance();
} catch (InstantiationException | IllegalAccessException e) {
e.printStackTrace();
return null;
}
распечатав generatedObject.getClass().getInterfaces()
действительно показывают, что MyInterface
реализуется. Но generatedObject instanceof MyInterface
возвращает false, то, что я нахожу противоречие.
Может ли кто-нибудь пролить свет на то, что здесь происходит? Любая помощь будет принята с благодарностью.
Это сделал это, спасибо. Оглядываясь назад, кажется очевидным, что класс не будет виден системному загрузчику. Еще раз спасибо! – Xyene
Помните: класс определяется его FQCN и загрузчиком классов, из которого он пришел! –