2015-06-16 24 views
8

Używam ByteBuddy do tworzenia klasy w czasie wykonywania z dynamicznie generowanym kodem bajtu. Wygenerowana klasa robi to, co ma zrobić, ale chcę ręcznie sprawdzić wygenerowany kod bajtu, aby upewnić się, że jest poprawny.Wyświetlanie wygenerowane przez bajt kodu bajtowego

Przykładowo

Class<?> dynamicType = new ByteBuddy() 
     .subclass(MyAbstractClass.class) 
     .method(named("mymethod")) 
     .intercept(new MyImplementation(args)) 
     .make() 
     .load(getClass().getClassLoader(), ClassLoadingStrategy.Default.WRAPPER) 
     .getLoaded(); 

gdy polecenia łańcuchy MyImplementation stwardnienie StackManipulation tworząc dynamicznie wygenerowany kod.

Czy mogę napisać wygenerowaną klasę do pliku, (aby można było ręcznie sprawdzać z IDE), lub w inny sposób wydrukować kod bajtowy dla wygenerowanej klasy?

+0

Jak wskazano, można zapisać plik jako plik klasy i sprawdzić go za pomocą * javap *. –

Odpowiedz

11

Możesz zapisać klasę jako .class pliku:

new ByteBuddy() 
    .subclass(Object.class) 
    .name("Foo") 
    .make() 
    .saveIn(new File("c:/temp")); 

Kod ten tworzy c:/temp/Foo.class.

2

Znajdź poniżej przykład przechowywania bajtów wygenerowanej klasy w tablicy bajtów. I w jaki sposób klasa może zostać zapisana w systemie plików i może być utworzona z tej tablicy.

import java.nio.file.Files; 
import java.nio.file.Paths; 
import java.nio.file.StandardOpenOption; 
import net.bytebuddy.ByteBuddy; 
import net.bytebuddy.instrumentation.FixedValue; 
import static net.bytebuddy.instrumentation.method.matcher.MethodMatchers.named; 

public class GenerateClass extends ClassLoader { 

    void doStuff() throws Exception { 
     byte[] classBytes = new ByteBuddy() 
       .subclass(Object.class) 
       .name("MyClass") 
       .method(named("toString")) 
       .intercept(FixedValue.value("Hello World!")) 
       .make() 
       .getBytes(); 

     // store the MyClass.class file on the file system 
     Files.write(Paths.get("MyClass.class"), classBytes, StandardOpenOption.CREATE); 

     // create an instance of the class from the byte array 
     Class<?> defineClass = defineClass("MyClass", classBytes, 0, classBytes.length); 
     System.out.println(defineClass.newInstance()); 
    } 

    public static void main(String[] args) throws Exception { 
     new GenerateClass().doStuff(); 
    } 
} 
+0

Dzięki SubOptimal. Przyjąłem odpowiedź saka1029, ponieważ była krótsza i osiągnęła to samo. – bramp

+0

@bramp Wszystko w porządku. Ponieważ odpowiedzi rozwiązują różne rzeczy. Odpowiedź od saka1029 generuje klasę i zapisuje ją do pliku. Moja odpowiedź generuje klasę, zapisz ją do pliku i możesz utworzyć instancję wygenerowanej klasy. Jeśli nie potrzebujesz tworzyć utworzonej klasy lub nie potrzebujesz dostępu do wygenerowanych bajtów, odpowiedź saka1029 jest drogą do zrobienia. – SubOptimal