2016-05-26 19 views
1

Ich experimentiere mit der ASM-Bibliothek.Abrufen von Feld in einer Klasse als Byte-Array

Ich habe eine Klasse gespeichert als byte[], dh beginnend mit CAFEBABE, mit einem konstanten Pool, etc.

Ich mag diese Klasse laden und ein Feld in einer Art und Weise so bequem wie möglich zu extrahieren, wie dieses Verfahren würde zu einer Methode mit ASM hinzugefügt werden.

Gibt es eine einfache Möglichkeit, ein Byte-Array als eine Klasse zu laden, ohne mit benutzerdefinierten Klassenlatern und dergleichen zu verwirren?

+0

Soweit ich weiß, bietet ASM Ihnen keine alternative API. Aber was ist falsch daran, eine Unterklasse von 'ClassLoader' zu erstellen (benötigt keine zusätzlichen Mitglieder) und' defineClass' darauf aufzurufen? – Holger

+0

Kann der Systemklassenlader nicht verwendet werden? – konsolas

+0

Die Methode 'defineClass' ist' protected'. Sie können Reflection und access override verwenden, um die Methode für den Systemklassenlader aufzurufen. Dies ist jedoch nicht einfacher als das Erstellen einer Unterklasse von 'ClassLoader' ohne zusätzliche Member. – Holger

Antwort

0

Bearbeiten: Misread die Frage. Sie möchten die Klasse buchstäblich laden?

static class BLoader extends ClassLoader { 
    public BLoader(ClassLoader parent) { 
     super(parent); 
    } 

    public Class<?> get(String name, byte[] bytes) { 
     return defineClass(name, bytes, 0, bytes.length); 
    } 
} 

Verwendet von:

Class<?> clazz = new BLoader(ClassLoader.getSystemClassLoader()).get("ClassName", cw.toByteArray()); 
0

Wir verwenden einen benutzerdefinierten Classloader, weil wir apublic defineClass() -Methode müssen. Alles, was Sie tun müssen, ist buchstäblich das.

public class GenericClassLoader extends ClassLoader { 

    public Class<?> defineClass(String name, byte[] b) { 
     return defineClass(name, b, 0, b.length); 
    } 

} 

Und um die Klasse zu laden.

GenericClassLoader classLoader = new GenericClassLoader(); 
Class<?> clazz = cl.defineClass("class name", classWriter.toByteArray()); 

Wenn Sie eine ClassNode haben und wollen auf den Namen der Klasse, die Klasse zu erzeugen, je Sie classNode.name verwenden können, wie diese.

Class<?> clazz = classLoader.defineClass(cn.name, classWriter.toByteArray());