Я хочу сделать что-то вроде этого:
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() );
Итак, я хочу посмотреть на все классы в моем юниверсе приложений, и когда я найду тот, который происходит от Animal, я хочу создать новый объект этого типа и добавить его в список. Это позволяет мне добавлять функциональность без обновления списка вещей. Я могу избежать следующего:
List<Animal> animals = new ArrayList<Animal>();
animals.add( new Dog() );
animals.add( new Cat() );
animals.add( new Donkey() );
...
С помощью описанного выше подхода я могу просто создать новый класс, расширяющий Animal, и он будет автоматически выбран.
ОБНОВЛЕНИЕ: 16.10.2008 9:00 по тихоокеанскому стандартному времени:
Этот вопрос вызвал много хороших ответов - спасибо. Из ответов и моих исследований я обнаружил, что то, что я действительно хочу сделать, просто невозможно в Java. Существуют подходы, такие как механизм ddimitrov ServiceLoader, который может работать, но они очень тяжелы для того, что я хочу, и я считаю, что я просто перенесу проблему из кода Java во внешний файл конфигурации. Обновление 5/10/19 (11 лет спустя!) В настоящее время есть несколько библиотек, которые могут помочь с этим согласно ответу @IvanNik org.reflections выглядит хорошо. Также интересно выглядит ответ ClassGraph от @Luke Hutchison. В ответах есть еще несколько возможностей.
Другой способ заявить, что я хочу: статическая функция в моем классе Animal находит и создает все классы, которые наследуются от Animal, без какой-либо дальнейшей настройки/кодирования. Если мне нужно настроить, я все равно могу просто создать их экземпляр в классе Animal. Я понимаю это, потому что Java-программа - это просто свободная федерация файлов .class, которая такова, как есть.
Интересно, что в С# это довольно тривиально.