Je joue avec Reflection et je pensais créer quelque chose qui chargerait une classe et afficherait le nom de tous les champs de la classe ..__ J'ai créé une petite classe de type hello world pour pouvoir inspecter:
kent@rat:~/eclipsews/SmallExample/bin$ ls
IndependentClass.class
kent@rat:~/eclipsews/SmallExample/bin$ Java IndependentClass
Hello! Goodbye!
kent@rat:~/eclipsews/SmallExample/bin$ pwd
/home/kent/eclipsews/SmallExample/bin
kent@rat:~/eclipsews/SmallExample/bin$
Sur la base de ce qui précède, je tire deux conclusions:
Ensuite, le code qui doit utiliser Reflection: (La ligne qui provoque une exception est marquée)
import Java.lang.reflect.Field;
import Java.net.MalformedURLException;
import Java.net.URL;
import Java.net.URLClassLoader;
public class InspectClass {
@SuppressWarnings("unchecked")
public static void main(String[] args) throws ClassNotFoundException, MalformedURLException {
URL classUrl;
classUrl = new URL("file:///home/kent/eclipsews/SmallExample/bin/IndependentClass.class");
URL[] classUrls = { classUrl };
URLClassLoader ucl = new URLClassLoader(classUrls);
Class c = ucl.loadClass("IndependentClass"); // LINE 14
for(Field f: c.getDeclaredFields()) {
System.out.println("Field name" + f.getName());
}
}
}
Mais quand je le lance, je reçois:
Exception in thread "main" Java.lang.ClassNotFoundException: IndependentClass
at Java.net.URLClassLoader$1.run(URLClassLoader.Java:200)
at Java.security.AccessController.doPrivileged(Native Method)
at Java.net.URLClassLoader.findClass(URLClassLoader.Java:188)
at Java.lang.ClassLoader.loadClass(ClassLoader.Java:306)
at Java.lang.ClassLoader.loadClass(ClassLoader.Java:251)
at InspectClass.main(InspectClass.Java:14)
Mes questions:
Depuis les Javadocs du constructeur URLClassLoader(URL[])
:
Construit un nouveau URLClassLoader pour les URL spécifiées à l'aide du ClassLoader parent de délégation par défaut. Les URL seront recherchées dans l'ordre spécifié pour les classes et les ressources après la première recherche dans le chargeur de classes parent. Toute URL se terminant par un '/' est supposée faire référence à un répertoire. Sinon, l'URL est supposée faire référence à un fichier JAR qui sera téléchargé et ouvert selon les besoins.
Donc, vous avez deux options:
(1) est plus facile dans ce cas, mais (2) peut être pratique si vous utilisez des ressources en réseau.
Vous devez fournir les répertoires ou les fichiers JAR contenant vos fichiers .class à URLClassLoader:
classUrl = new URL("file:///home/kent/eclipsews/SmallExample/bin/");
Et oui, vous pouvez charger autant de classes que vous le souhaitez
Vous devez charger la classe en donnant le nom de classe complet qui est le nom de classe avec son chemin de package comme
Class c = ucl.loadClass("com.mypackage.IndependentClass");
J'avais un problème similaire mais mon fichier de classe résidait dans un paquet nommé "customElements". Dans de tels scénarios, l'URL doit être construite jusqu'au dossier situé juste au-dessus du package racine et dans la méthode de chargement, le nom complet de la classe, package compris, doit être transmis. Par exemple, dans mon cas; L'URL était comme:
File customElementsDir = new File("D:/My Space");
//File customElementsDir = new File("D:\\customElements");
URL[] urls = null;
try {
URL url = customElementsDir.toURI().toURL();
urls = new URL[] { url };
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Et le chargement réel était comme:
clazz = childFirstClassLoader
.loadClass("customElements.CustomLoadableClass");
Où childFirstClassLoader est mon chargeur de classe.