441 votes

Pouvez-vous trouver toutes les classes dans un package à l'aide de la réflexion?

Une question de débutant sur la réflexion, je suppose:

Est-il possible de retrouver l'ensemble des interfaces ou des classes dans un package donné? (Rapidement, en regardant par exemple, Package, il semblerait que non.)

314voto

Staale Points 8795

En raison de la nature dynamique de la classe chargeurs, ce n'est pas possible. Classe chargeurs ne sont pas tenus de dire la VM qui le classe peut fournir, au lieu de cela, ils sont juste remis les demandes pour les classes, et de retourner une classe ou lever une exception.

Toutefois, si vous écrivez votre propre classe chargeurs, ou d'examiner les chemins de classe et c'est des pots, il est possible de trouver cette information. Ce sera via les opérations de système de fichiers et non de la réflexion. Il y a même des bibliothèques qui peuvent vous aider à le faire.

Si il y a des cours qui se produit, ou remis à distance, vous ne serez pas en mesure de découvrir ces classes.

La méthode normale est plutôt quelque part enregistrer les classes dont vous avez besoin d'accéder à un fichier, ou d'une référence dans une autre classe. Ou tout simplement utiliser de la convention lorsqu'il s'agit de les nommer.

Addendum: Les Réflexions de la Bibliothèque vous permettra de regarder les classes dans le courant de classpath. Il peut être utilisé pour obtenir toutes les classes dans un package:

 Reflections reflections = new Reflections("my.project.prefix");

 Set<Class<? extends Object>> allClasses = 
     reflections.getSubTypesOf(Object.class);

159voto

Vous devriez probablement prendre un coup d'oeil à l'open source de Réflexions de la bibliothèque. Avec elle, vous pouvez facilement obtenir ce que vous voulez.

D'abord, le programme d'installation les réflexions de l'index (c'est un peu brouillon, depuis la recherche de toutes les classes est désactivée par défaut):

List<ClassLoader> classLoadersList = new LinkedList<ClassLoader>();
classLoadersList.add(ClasspathHelper.contextClassLoader());
classLoadersList.add(ClasspathHelper.staticClassLoader());

Reflections reflections = new Reflections(new ConfigurationBuilder()
    .setScanners(new SubTypesScanner(false /* don't exclude Object.class */), new ResourcesScanner())
    .setUrls(ClasspathHelper.forClassLoader(classLoadersList.toArray(new ClassLoader[0])))
    .filterInputsBy(new FilterBuilder().include(FilterBuilder.prefix("org.your.package"))));

Ensuite, vous pouvez faire une requête pour tous les objets dans un paquet de:

Set<Class<?>> classes = reflections.getSubTypesOf(Object.class);

104voto

Christoph Leiter Points 4350

Google Goyave 14 comprend une nouvelle classe ClassPath avec trois méthodes d'analyse de haut niveau des classes:

  • getTopLevelClasses()
  • getTopLevelClasses(String packageName)
  • getTopLevelClassesRecursive(String packageName)

Voir l' ClassPath documentation javadoc pour plus d'info.

85voto

Amit Points 5760

Vous pouvez utiliser cette méthode énumérés à http://snippets.dzone.com/posts/show/4831en utilisant le chargeur de classe.

75voto

voho Points 134

Certains outils sont également disponibles dans Google Goyave 14. Voir ceci:

final ClassLoader loader = Thread.currentThread().getContextClassLoader();

for (final ClassPath.ClassInfo info : ClassPath.from(loader).getTopLevelClasses()) {
  if (info.getName().startsWith("my.package.")) {
    final Class<?> clazz = info.load();
    // do something with your clazz
  }
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by: