2013-02-13 58 views
2

我試圖重命名使用ASM 4.0類:如何用ASM重命名一個類,並保持在同一個類加載器中?

ClassReader reader = new ClassReader(
    loader.getResourceAsStream("test/MyClass.class") 
); 
ClassWriter writer = new ClassWriter(reader, 0); 
ClassVisitor visitor = new RemappingClassAdapter(visitor, new Remapper() { /* skipped */ }); 
reader.accept(visitor, 0); 
return new ClassLoader() { 
    public Class<?> load(final String name, final byte[] bytes) { 
     return this.defineClass(name, bytes, 0, bytes.length); 
    } 
}.load("test/MyClass", writer.toByteArray()); 

我故意跳過重命名的一部分。一個新班級應該是原始班級的精確副本。它是,但它不能再作爲一箇舊的使用:

java.lang.ClassCastException: test.MyClass cannot be cast to test.MyClass 

如何留在相同的類加載器?

回答

1

在JVM中,每個類都由它的完全限定名稱和加載類的類加載器來標識。這解釋了你的ClassCastException。

一旦你重新命名這個類,你應該可以在任何類加載器中加載你的重命名類。使用反射來獲取「ClassLoader.defineClass()」方法,並使用它在getClass()上調用它。getClassLoader();

Method m=ClassLoader.class.getDeclaredMethod("defineClass", 
String.class,byte[].class,int.class,int.class) 
m.setAccessible(true); 
m.invoke(getClass().getClassLoader(), ...) 
相關問題