2013-03-19 18 views
5

Sto generando una classe dinamica nel mio programma java scrivendo tutto il mio codice in un file java, compilando il file java in un file di classe e quindi caricando il file di classe con un URLClassLoader. Il problema con questo è che crea molti file sul mio computer. È un modo per farlo solo creando "file virtuali" (oggetti file) e non generando alcun file effettivo, perché il modo in cui lo fa richiede tempo e sembra impuro e inefficiente.Generazione di Dynamic Class Java

+0

http://docs.oracle.com/javase/6/docs/api/javax/tools/JavaCompiler.html? – Affe

+0

ma non ho ancora bisogno di creare il file .java in modo che io possa compilarlo –

+0

vedere l'esempio JavaSourceFromString per una possibile soluzione nel link di @Affe. – Pyranja

risposta

1

Se si guarda alla classe ClassLoader, ha un metodo per definire una classe dalla serie effettiva di byte.

Java docs for ClassLoader

Ammetto che non ho lavorato con caricatori di classe su questo basso livello, ma la mia comprensione è che questo è un modello di template, in cui la classe base ClassLoader sa come creare una classe nel VM basato su codice byte grezzo. Le classi figlie sono responsabili di capire dove trovare il codice byte per una determinata classe.

Quindi la soluzione per voi potrebbe essere quella di smettere di usare completamente URLClassLoader ed estendere ClassLoader da soli.

+0

che sembra un po 'complicato –

+1

I caricatori di classe di solito sono ... – Brandon

0

A (più) soluzione semplice sarebbe quella di effettuare le seguenti operazioni:

  • compilare il file di classe in una directory comune
  • Creare un costume ClassLoader che si estende ClassLoader
  • Utilizzare questa ClassLoader da leggere in i file .class.

Ecco qualcosa per iniziare - Lascerò l'esercizio di ottenere il codice byte nell'oggetto come un esercizio per il lettore. (Non è molto difficile, se si utilizza un po 'di lavoro in questo SimpleFileVisitorCheck 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. 
    } 

} 

è possibile utilizzare in questo modo:

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

... a condizione che esso didn' t lanciare un'eccezione o tornare nulla.

+0

questo è quello che sto facendo il problema è che non voglio creare alcun file fisico –

+0

...ma hai detto che stavi compilando la classe da qualche parte, giusto? Non è un problema enorme se hai un sacco di file .class; quelli possono essere rimossi in modo sicuro dopo aver finito ... – Makoto

+0

so che non sembra pulito –

0

Le librerie di generazione e manipolazione di codice byte consentono di modificare e generare classi al volo, in memoria. Javassist è probabilmente il modo più semplice per iniziare poiché consente di utilizzare la sintassi Java.

Inoltre tendono ad essere più leggeri di interi compilatori standalone.