Tôi muốn làm một cái gì đó như thế này:
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() );
Vì vậy, tôi muốn xem xét tất cả các lớp trong vũ trụ của ứng dụng của mình và khi tôi tìm thấy một lớp xuất phát từ Animal, tôi muốn tạo một đối tượng mới thuộc loại đó và thêm nó vào danh sách. Điều này cho phép tôi thêm chức năng mà không phải cập nhật danh sách các thứ. Tôi có thể tránh những điều sau đây:
List<Animal> animals = new ArrayList<Animal>();
animals.add( new Dog() );
animals.add( new Cat() );
animals.add( new Donkey() );
...
Với cách tiếp cận trên, tôi có thể chỉ cần tạo một lớp mới mở rộng Animal và nó sẽ tự động được chọn.
CẬP NHẬT: 16/10/2008 9:00 sáng Giờ chuẩn Thái Bình Dương:
Câu hỏi này đã tạo ra rất nhiều câu trả lời tuyệt vời - cảm ơn bạn. Từ các phản hồi và nghiên cứu của tôi, tôi đã thấy rằng những gì tôi thực sự muốn làm là không thể thực hiện được trong Java. Có nhiều cách tiếp cận, chẳng hạn như cơ chế ServiceLoader của ddimitrov có thể hoạt động - nhưng chúng rất nặng đối với những gì tôi muốn và tôi tin rằng tôi chỉ đơn giản chuyển vấn đề từ mã Java sang tệp cấu hình bên ngoài. Cập nhật 5/10/19 (11 năm sau!) Hiện tại có một số thư viện có thể trợ giúp việc này theo câu trả lời org.reflections của @ IvanNik có vẻ tốt. Ngoài ra ClassGraph từ câu trả lời của @Luke Hutchison có vẻ thú vị. Có nhiều khả năng hơn trong các câu trả lời là tốt.
Một cách khác để nói lên những gì tôi muốn: một hàm tĩnh trong lớp Animal của tôi tìm và khởi tạo tất cả các lớp kế thừa từ Animal - mà không cần thêm bất kỳ cấu hình / mã hóa nào. Nếu tôi phải cấu hình, tôi cũng có thể khởi tạo chúng trong lớp Animal. Tôi hiểu điều đó bởi vì một chương trình Java chỉ là một liên kết lỏng lẻo của các tệp. Class, chính là như vậy.
Thật thú vị, có vẻ như điều này khá tầm thường trong C #.