我正在使用ASM的ClassWriter复制一个类。我使用反射将具有此重复字节代码的类加载,但是,当我尝试使用重复的类实例调用重复类的方法时,出现“对象不是声明类的实例”异常。
Object originalObj = ...
Class<?> originalClass = obj.getClass();
String methodName = ...
ClassReader cr = new ClassReader(originalClass.getName());
ClassWriter cw = new ClassWriter(0);
cr.accept(cw, 0);
DynamicClassLoader loader = new DynamicClassLoader();
Class<?> c = loader.define(originalClass.getName(), cw.toByteArray());
Method m = c.getMethod(methodName); // Assume 'methodName' has no args
m.setAccessible(true);
m.invoke(originalClass.cast(originalObj));
最佳答案
加载的Java类型由两个参数组成:
类型的全限定名。
用于加载此类型的ClassLoader
。
这意味着类型[com.example.Foo, ClassLoaderA]
和[com.example.Foo, ClassLoaderB]
不相等。因此,您不能将第一种类型转换为第二种类型。创建实例后,您根本无法更改其类型。
线
originalClass.cast(originalObj)
无效,因为
originalObj
已经是originalClass
的实例。尽管名称相同,但是复制的类c
不能分配给orginalClass
。看一下Java instrumentation API来更改已经加载的类。