Java Language Chargement d'un fichier .class externe


Exemple

Pour charger une classe, il faut d'abord la définir. La classe est définie par le ClassLoader . Il n'y a qu'un seul problème, Oracle n'a pas écrit le ClassLoader du ClassLoader avec cette fonctionnalité disponible. Pour définir la classe, nous devrons accéder à une méthode appelée defineClass() qui est une méthode privée du ClassLoader .

Pour y accéder, nous allons créer une nouvelle classe, ByteClassLoader , et l'étendre à ClassLoader . Maintenant que nous avons étendu notre classe à ClassLoader , nous pouvons accéder aux méthodes privées du ClassLoader . Pour rendre defineClass() disponible, nous allons créer une nouvelle méthode qui agira comme un miroir pour la defineClass() private defineClass() . Pour appeler la méthode privée , nous aurons besoin du nom de la classe, le name , les octets de classe, classBytes , crédits compensatoires du premier octet, qui sera 0 parce que classBytes les données commence à classBytes[0] , et le décalage de dernier octet, qui sera classBytes.lenght car il représente la taille des données, qui sera le dernier décalage.

public class ByteClassLoader extends ClassLoader {

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

}

Maintenant, nous avons une defineClass() publique defineClass() . Il peut être appelé en passant le nom de la classe et les octets de la classe comme arguments.

Disons que nous avons une classe nommée MyClass dans le paquet stackoverflow ...

Pour appeler la méthode, nous avons besoin des octets de classe, nous créons donc un objet Path représentant notre chemin de classe en utilisant la méthode Paths.get() et en passant le chemin de la classe binaire en argument. Maintenant, nous pouvons obtenir les octets de classe avec Files.readAllBytes(path) . Nous créons donc une instance de ByteClassLoader et utilisons la méthode que nous avons créée, defineClass() . Nous avons déjà les octets de classe, mais pour appeler notre méthode, nous avons également besoin du nom de classe qui est donné par le nom du paquet (point), le nom canonique de la classe, dans ce cas stackoverflow.MyClass .

Path path = Paths.get("MyClass.class");

ByteClassLoader loader = new ByteClassLoader();
loader.defineClass("stackoverflow.MyClass", Files.readAllBytes(path);

Remarque : La méthode defineClass() renvoie un objet Class<?> . Vous pouvez le sauvegarder si vous le souhaitez.

Pour charger la classe, il suffit d'appeler loadClass() et de passer le nom de la classe. Cette méthode peut lancer une ClassNotFoundException ; nous devons donc utiliser un bloc try cath

try{
    loader.loadClass("stackoverflow.MyClass");
} catch(ClassNotFoundException e){
    e.printStackTrace();
}