2009-07-06 11 views
17

Powiel możliwe:
How do you find all subclasses of a given class in Java?Czy można uzyskać wszystkie podklasy klasy?

Cześć,

Chciałbym uzyskać listę klas, które implementują interfejs w języku Java w czasie wykonywania więc mogę zrobić usługi wyszukiwania bez konieczności do twardego kodu. Czy istnieje prosty sposób na zrobienie tego? Nie boję się.

+1

W języku C# można to zrobić, wykonując iterację definicji każdej klasy w zespole i testując każdą z tych klas, aby sprawdzić, czy implementuje ten interfejs. – ChrisW

+3

Niestety, pytanie nie dotyczy C#. – Tom

+1

Duplikat? "Jak znaleźć wszystkie podklasy danej klasy w Javie?", Http://stackoverflow.com/questions/492184/how-do-you-find-all-subclasses-of-a-given-class-in- java – Jonik

Odpowiedz

24

Krótka odpowiedź brzmi: nie.

Długą odpowiedzią jest to, że podklasy mogą powstawać na wiele sposobów, co zasadniczo uniemożliwia ich kategoryczne odnalezienie.

Nie możesz tego zrobić w czasie wykonywania, ale nie możesz znaleźć zajęć, dopóki nie zostaną załadowane i skąd wiadomo, że zostały załadowane? Możesz skanować każdy plik JAR i klasy, ale to nie jest ostateczne. Poza tym są takie rzeczy, jak ładowniki klas adresów URL.

Klasy wewnętrzne (statyczne i niestatyczne) to kolejny przypadek do rozważenia. Nazwane klasy wewnętrzne są łatwiejsze do znalezienia. Anonimowe klasy wewnętrzne są potencjalnie znacznie trudniejsze do znalezienia.

Należy również wziąć pod uwagę, że jeśli klasa ma podklasy, wówczas nowe podklasy mogą być tworzone w późniejszym czasie.

-2

Jeśli ładujesz klasy tylko z dysku lub z adresów URL, możesz zeskanować ścieżkę klasy i znaleźć podklasy "ręcznie".

0

Próbuję zrozumieć tę odpowiedź, więc prawdopodobnie jestem w błędzie. Dla klasy nie ma sensu posiadanie informacji na temat jej potomków lub podklas, ponieważ w dowolnym momencie ktoś może stworzyć nową podklasę twojej klasy. Następnie musisz przekompilować swoją klasę, aby za każdym razem zawierała te nowe informacje. To nie ma sensu dla rozszerzalnego kodu. Bardziej prawdopodobne jest, że klasa zawiera informacje o swoich przodkach. Tak więc jedynym rozwiązaniem, które mogę zobaczyć, jest powtórzenie każdej klasy w przestrzeni problemu i sprawdzenie, ale jest to bardziej niż prawdopodobne, straszne rozwiązanie dla ciebie.

1

Zawsze mogę utworzyć nową podklasę dla każdej klasy nieostatecznej, dodać podklasę do ścieżki klasy i pokonać twoje intencje. Podklasy to otwarta propozycja.

O najlepszych rzeczach, które możesz zrobić, to powiedzieć, że dla danej klasy ścieżki wiesz, jakie są podklasy, i aby to zrobić, musisz przeskanować każdą klasę w ścieżce klas.

1

To dość proste za pomocą refleksji. Przeczytaj ten artykuł z JavaWorld

http://www.javaworld.com/javaworld/javatips/jw-javatip113.html

+0

Źle odczytałem pytanie, powyższy artykuł służy tylko znalezieniu podklas implementujących dany interfejs –

+0

Ten kod skanuje tylko szczególny pakiet. Ale podklasy mogą istnieć w dowolnym pakiecie. W artykule napisano: "interesują nas wszystkie klasy implementujące dany interfejs, żadne informacje nie są dostępne za pośrednictwem Java Reflection". –

1

Jedynym sposobem, byłbyś w stanie zrobić to idzie hierarchii pakiet dla pakietów dostępnych w ścieżce klasy sprawdzanie każdej klasy za pośrednictwem refleksji (i to będzie ssać bo ciebie” Skutecznie załaduję każdą klasę, chyba że ograniczysz wyszukiwanie do określonych pakietów.

Kłopot z tym rodzajem auto-magicznego zachowania polega na tym, że trudne staje się ilościowe określenie aplikacji bez jej uruchamiania, co jest bóle głowy konserwacji. Zawsze wolałbym jechać drogą wtrysku (a-la Spring) przez instancje poprzez jakąś konfigurację.

0

Czy chcesz wyliczyć klasy, które implementują określony interfejs lub wyliczyć klasy, które pochodzą z pewnej klasy bazowej? To są dwa różne problemy. Oba, o ile wiem, byłyby trudne do wdrożenia, ponieważ nowe implementacje mogą być tworzone/instalowane na komputerze w dowolnym momencie w przyszłości. Wygląda na to, że próbujesz utworzyć metodę fabularną, aby utworzyć instancję konkretnej instancji, i nie chcesz, aby nazwa klasy była sztywno zakodowana w kodzie. Zwykle za pomocą pliku konfiguracyjnego, który wylicza wszystkie klasy, które implementują interfejs jest drogą do zrobienia (lub można użyć bazy danych). Gdy nowe klasy implementują interfejs, dodajesz je do pliku konfiguracyjnego, a fabryka powinna pobrać nową nazwę klasy.

5

należy użyć Java ServiceLoader, która jest klasą wbudowaną. Jest zdolny do iterowania w czasie wykonywania we wszystkich implementacjach znanego serwisu (interfejsu).

Jeśli z jakiegoś powodu nie chcesz tego, możesz użyć ClassLoader.getSystemResources() do iterowania wszystkich zasobów; na przykład jeśli masz 6 razy plik /META-INF/com.interface dostaniesz 6 iteracji.

Powiązane problemy