2013-03-19 87 views
5

我寫我所有的代碼放到一個java文件,編譯Java文件轉換成一個類文件,然後加載與URLClassLoader的類文件生成我的java程序動態類。問題在於它在我的電腦上創建了很多文件。他們是僅僅創建「虛擬文件」(文件對象)而不生成任何實際文件的方式,因爲我這樣做的方式需要時間並且看起來不夠清晰且效率低下。生成動態級Java

+0

http://docs.oracle.com/javase/6/docs/api/javax/tools/JavaCompiler.html? – Affe 2013-03-19 23:55:53

+0

但我不需要創建.java文件,以便我可以編譯它 – 2013-03-19 23:58:07

+0

請參閱JavaSourceFromString示例,瞭解@Affe鏈接中可能的解決方案。 – Pyranja 2013-03-20 00:00:43

回答

1

如果你看看ClassLoader類,它必須從實際的字節序列定義一個類的方法。

Java docs for ClassLoader

我承認我還沒有與類加載器對如此低的水平的工作,但我的理解是,這是一個模板模式,其中基礎ClassLoader類知道如何在虛擬機創建一個類基於原始字節碼。子類負責確定在哪裏找到給定類的字節碼。

所以您的解決方案可能會停止使用URLClassLoader的完全和自己的ClassLoader延伸。

+0

加載它似乎有點複雜 – 2013-03-20 00:03:47

+1

類加載器通常是... – Brandon 2013-03-20 00:04:10

0

A(更)簡單的解決辦法是做到以下幾點:

  • 編譯您的類文件到一個共同的目錄
  • 創建一個自定義ClassLoader延伸ClassLoader
  • 使用此ClassLoader閱讀.class文件。

這裏有一些東西讓你開始 - 我將把字節碼作爲練習留給讀者。 (如果你使用一些SimpleFileVisitor工作,在此,是不是很困難Check out Java.NIO.

public class CustomClassLoader extends ClassLoader { 

    @Override 
    public Class findClass(String binaryClassName) { 
     byte[] b = customLoadClassData(binaryClassName); 
     return defineClass(binaryClassName, b, 0, b.length); 
    } 

    private byte[] customLoadClassData(String binaryClassName) { 
     // Be sure to read in the specific .class file you want. 
     // A tip is to handle this *outside* of this class. 
    } 

} 

然後,您可以使用它像這樣:

CustomClassLoader loader = new CustomClassLoader(); 
Class clazz = loader.findClass("com.stackoverflow.some.binary.name"); 

...只要它沒」 t拋出異常或返回null。

+0

多數民衆贊成什麼IM做的問題是,我不希望創建任何物理文件 – 2013-03-20 00:16:21

+0

...但你確實提到你正在編譯這個類,對吧?如果你有大量的.class文件,這不是一個大問題;那些可以安全地刪除後,你完成... – Makoto 2013-03-20 00:19:07

+0

我知道它只是看起來不乾淨 – 2013-03-20 00:31:19

0

字節代碼生成和操作庫允許您在內存中即時修改和生成類。因爲它允許使用Java語法,因此可能最容易使用Javassist

它們也傾向於比整個獨立編譯器更輕。