2014-03-13 170 views
0

我正在使用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)); 
+0

originalObj被聲明爲Object,因此將無法訪問您的方法。你必須originalClass.cast(...)它的類型來調用方法... –

+0

@GermannArlington感謝您的建議,但不幸的是,例外仍然發生 – user973758

+0

如果我嘗試使用c投擲originalObject我得到一個ClassCastException - 但c和originalClass具有相同的字節碼,爲什麼這是一個問題? – user973758

回答

3

一個加載 Java類型由兩個參數組成:

  1. 類型的全名。用於加載此類型的ClassLoader

這意味着類型和[com.example.Foo, ClassLoaderB]不相等。因此,您不能將第一種類型轉換爲第二種類型。一旦創建了一個實例,就無法改變它的類型。

originalClass.cast(originalObj) 

沒有任何影響,因爲originalObj已經是originalClass一個實例。但是,複製的類c不能分配給orginalClass,儘管名稱相同。

查看Java instrumentation API用於更改已加載的類。

相關問題