Je veux faire quelque chose comme ça:
List<Animal> animals = new ArrayList<Animal>();
for( Class c: list_of_all_classes_available_to_my_app() )
if (c is Animal)
animals.add( new c() );
Donc, je veux regarder toutes les classes de l'univers de mon application, et quand j'en trouve une qui descend d'Animal, je veux créer un nouvel objet de ce type et l'ajouter à la liste. Cela me permet d'ajouter des fonctionnalités sans avoir à mettre à jour une liste de choses. Je peux éviter ce qui suit:
List<Animal> animals = new ArrayList<Animal>();
animals.add( new Dog() );
animals.add( new Cat() );
animals.add( new Donkey() );
...
Avec l'approche ci-dessus, je peux simplement créer une nouvelle classe qui étend Animal et elle sera automatiquement récupérée.
MISE À JOUR: 16/10/2008 9h00, heure normale du Pacifique:
Cette question a généré beaucoup de bonnes réponses - merci. D'après les réponses et mes recherches, j'ai trouvé que ce que je veux vraiment faire n'est tout simplement pas possible sous Java. Il existe des approches, telles que le mécanisme ServiceLoader de ddimitrov qui peuvent fonctionner - mais elles sont très lourdes pour ce que je veux, et je crois que je déplace simplement le problème du code Java vers un fichier de configuration externe. Mise à jour 10/05/19 (11 ans plus tard!) Il existe maintenant plusieurs bibliothèques qui peuvent vous aider, selon la réponse de @ IvanNik org.reflections semble bonne. Aussi ClassGraph de @Luke de Hutchison réponse semble intéressante. Il y a aussi plusieurs autres possibilités dans les réponses.
Une autre façon de dire ce que je veux: une fonction statique dans ma classe Animal trouve et instancie toutes les classes qui héritent d'Animal - sans autre configuration / codage. Si je dois configurer, je pourrais tout aussi bien les instancier dans la classe Animal de toute façon. Je comprends cela parce qu'un programme Java est juste une fédération lâche de fichiers .class que c'est comme ça.
Fait intéressant, il semble que ce soit assez trivial en C #.