我正在編寫一個應用程序,需要在運行時重新加載以前加載的類。原因是該類是在運行時自動生成的,而新的實現會改變應用程序的工作方式。我只生成上述類的一個對象,並從所有依賴中剝離它,但是它定義了常量值的接口。在重新加載時重新設置任何或所有成員的值都沒有問題。我確切知道它何時發生變化,我可以控制它。我唯一的問題是重新加載。如何重新加載在運行時更改的以前加載的類?
從我讀的,我應該使用ClassLoader。我試圖這樣做,但我無法使它工作。
我試過如下:
- 獲取當前的ClassLoader(
myClassObject.getClass().getClassLoader()
),並用它來重新加載類 - 不工作。它可能會不斷加載舊的實現。 - 生成我自己的(從修改後的AKA複製粘貼) - 不起作用,因爲我生成的ClassLoader不同於生成該類的類(例外:myClass不能被轉換爲myClass)。
- 創建一個設置超類ClassLoader的構造函數似乎沒有任何效果。
- 使用我的新ClassLoader生成myClassObject作爲成員的類解決了myClassObject的ClassLoader不匹配問題,但創建了一個新的不匹配級別。我每次都使用
getClassLoader()
,我發現它們不匹配。 - 我試着添加
-Djava.system.class.loader=com.test.Reoader com.test.myMainClass
使它成爲我的默認重裝器,但是我從編譯器中得到一個錯誤。 - 谷歌一直指着我回到我已經讀過的東西。
- 編輯:我試着創建一個接口並重新加載實現它的類。這也沒有解決它。
我知道我應該重寫默認的ClassLoader,但我沒有做任何事情似乎成功了。
我的ClassLoader:
public class Reloader extends ClassLoader {
public Reloader(){
super(Reloader.class.getClassLoader());
}
@Override
public Class<?> loadClass(String s) {
return findClass(s);
}
@Override
public Class<?> findClass(String s) {
try {
byte[] bytes = loadClassData(s);
return defineClass(s, bytes, 0, bytes.length);
} catch (IOException ioe) {
try {
return super.loadClass(s);
} catch (ClassNotFoundException ignore) {}
ioe.printStackTrace(java.lang.System.out);
return null;
}
}
private byte[] loadClassData(String className) throws IOException {
File f = new File("out\\production\\ManoCPU\\" + className.replaceAll("\\.", "/") + ".class");
int size = (int) f.length();
byte buff[] = new byte[size];
FileInputStream fis = new FileInputStream(f);
DataInputStream dis = new DataInputStream(fis);
dis.readFully(buff);
dis.close();
return buff;
}
}
非常感謝任何人都可以提供幫助。
該班如何自動生成? – nakosspy
我有一個編譯器讀取模板文件並將其編譯爲java代碼。模板文件可以在應用程序中更改和編譯。 – YMI
它是否經常發生?我的意思是班級可以重新編譯多少次? – nakosspy