2013-03-19 24 views
5

Generuję klasę dynamiczną w moim programie java, pisząc cały mój kod do pliku java, kompilując plik java do pliku klasy, a następnie ładując plik klasy za pomocą obiektu URLClassLoader. Problem polega na tym, że tworzy on wiele plików na moim komputerze. Czy jest to sposób, aby to zrobić, tworząc tylko "pliki wirtualne" (obiekty plików) i nie generując żadnych rzeczywistych plików, ponieważ sposób w jaki to robię wymaga czasu i wydaje się nieczysty i nieefektywny.Generowanie klasy Dynamic Java

+0

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

+0

ale nadal nie muszę tworzyć pliku .java, aby można go skompilować –

+0

zobacz przykład JavaSourceFromString dla możliwego rozwiązania w linku @Affe. – Pyranja

Odpowiedz

1

Jeśli spojrzysz na klasę ClassLoader, ma ona metodę definiowania klasy z rzeczywistej serii bajtów.

Java docs for ClassLoader

muszę przyznać, że nie współpracował z ładowarki klasy na tej niskiego poziomu, ale mój zrozumienia jest to, że jest to wzór szablonu, gdzie klasa bazowa ClassLoader wie, jak utworzyć klasę w VM oparty na kodzie bajtowym. Klasy potomne są odpowiedzialne za ustalenie, gdzie znaleźć kod bajtu dla danej klasy.

Rozwiązaniem dla Ciebie może być całkowite zaprzestanie używania narzędzia URLClassLoader i samodzielne rozszerzanie ClassLoadera.

+0

, który wydaje się nieco skomplikowany –

+1

Ładowarki klas zwykle są ... – Brandon

0

A (więcej) rozwiązanie proste byłoby wykonać następujące czynności:

  • skompilować plików klas do wspólnego katalogu
  • Tworzenie niestandardowego ClassLoader który rozciąga ClassLoader
  • Użyj tego ClassLoader czytać w pliki .class.

Oto coś, od czego zaczniesz - zostawiam ćwiczenie polegające na pobraniu kodu bajtowego do obiektu jako ćwiczenie dla czytelnika. (To nie jest bardzo trudne, jeśli użyć nieco SimpleFileVisitor pracy w tym 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. 
    } 

} 

Następnie można go używać tak:

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

... pod warunkiem, że nie zrobił” t wyrzuć wyjątek lub wróć null.

+0

to co robię to problem to, że nie chcę tworzyć żadnych plików fizycznych –

+0

...ale wspominałeś, że gdzieś tam kompilujesz, prawda? To nie jest wielki problem, jeśli masz mnóstwo plików .class; można je bezpiecznie usunąć po skończeniu ... – Makoto

+0

Wiem, że to po prostu nie wygląda na czyste –

0

Biblioteki generowania i manipulacji kodu bajtowego umożliwiają modyfikowanie i generowanie zajęć w locie, w pamięci. Javassist jest prawdopodobnie najłatwiejszy, ponieważ pozwala na użycie składni Java.

Mają również tendencję do bycia lżejszą niż całe autonomiczne kompilatory.