2009-08-05 14 views
8

Jeśli masz metodę z podpisem:Java generized klasa referencyjna

Class<? extends List<String>> getObjectType() 
{ 
     return ?????; 
} 

Jak powrócić do odpowiedniej wersji rodzajowe klasy liście?

return List.class; //errors 
return List<String>.class; //errors 
return List.class<String>; //errors 

jaka jest właściwa składnia do obsługi tego?

Odpowiedz

9

Musisz jawnie rzucić go do typu zwrotu. To działa:

return (Class<? extends List<String>>) List.class; 

Tak po prostu wygląda źle. To tylko jeden z wielu powodów, dla których system generyczny Java jest bałaganem.

+0

Ciekawe, robi swoje sugestie dostaje mnie bliżej jak zaćmienie przestaje sędzią. ale kiedy idę do kompilacji klasy z kompilatorem Java, otrzymuję "typy niemożliwe do wykrycia: java.lang.Class required: java.lang.Class > " –

+0

Nieparzyste, działa dla mnie w czasie zaćmienia, ale nie podczas kompilacji w linii poleceń. Nigdy wcześniej tego nie widziałem. –

+0

Opcja -nowarn działa w przypadku zwracania someList.getClass(), ale nadal dostaję ten sam błąd, który widzisz podczas próby z List.class. –

2

Musisz zwrócić klasę czegoś, co rozszerza się o List<String>. Jednym z przykładów jest ArrayList<String>. Można spróbować:

ArrayList<String> myList = new ArrayList<String>(); 
... 
return (Class<? extends List<String>>)myList.getClass(); 
+1

Wymagana jest wyraźna obsada. Ogólna metoda getClass zwraca typ Class . –

+0

@John: Dzięki za wskazanie tego. Sprawdziłem, i tak właśnie jest. Zaktualizowałem swój przykład, aby dołączyć obsadę. –

5

Z książki „Efektywne Java” (drugie wydanie, strona 137): „Nie używać typów wieloznacznych jako typy powrotów Zamiast zapewnia dodatkową elastyczność dla użytkowników, to zmusić ich do. używaj symboli wieloznacznych w kodzie klienta. "

Powiedział, oddanych, trzeba najpierw utworzyć zmienną tymczasową:

@SuppressWarnings("unchecked") 
Class<? extends List<String>> result = ....; 
return result; 

To działa, ponieważ można mieć adnotacje dotyczące zadań. Nie działa on sam na samej return. Można również dodać to do metody, ale także ukryć inne problemy.

+1

Dla mnie to nie tylko ostrzeżenie, to faktycznie wyprodukował błąd kompilacji, dopóki nie dodałem obsady. –

+0

Prawidłowo. "Lista" i "Lista <...>" są całkowicie różnymi typami (podobnie jak String i Integer), więc potrzebujesz obsady. Ale obsada spowoduje ostrzeżenie i musisz to powstrzymać. –

0

List.class i lista <String> .class - we wszystkich tych przypadkach potrzebujesz odlewania. Naprawdę trzeba typ, który ma listy <String> w czasie wykonywania, somethig tak:

interface StringList extends List<String> {}; 

public Class<? extends List<String>> getObjectType() { 
    return StringList.class; 
}