Moje pytanie jest takie jak powyżej. Przepraszamy, prawdopodobnie jest to duplikat, ale nie mogłem znaleźć przykładu z <?>
końcówką.
Dlaczego nie miałbyś używać tylko Class
jako parametru?
Moje pytanie jest takie jak powyżej. Przepraszamy, prawdopodobnie jest to duplikat, ale nie mogłem znaleźć przykładu z <?>
końcówką.
Dlaczego nie miałbyś używać tylko Class
jako parametru?
Odpowiedzi:
Class
jest klasą parametryzowalną, dlatego możesz użyć składni, Class<T>
gdzie T
jest typem. Pisząc Class<?>
, deklarujesz Class
obiekt, który może być dowolnego typu ( ?
jest to symbol wieloznaczny). Class
Typ to typ, który zawiera meta-informacje na temat klasy.
Zawsze dobrze jest odnosić się do typu ogólnego, określając jego konkretny typ, używając Class<?>
, przestrzegając tej praktyki (jesteś świadomy Class
możliwości parametryzacji), ale nie ograniczasz swojego parametru do określonego typu.
Źródła informacji na temat typów ogólnych i symboli wieloznacznych: http://docs.oracle.com/javase/tutorial/java/generics/wildcards.html
Odniesienie o Class
obiekcie i odbiciu (funkcja języka Java używana do introspekcji): https://www.oracle.com/technetwork/articles/java/javareflection-1536171.html
Class
bez typu? Wydają się reprezentować to samo.
?
symbol wieloznaczny”. . Jeśli nie podasz symbolu wieloznacznego, kompilator założy, że albo zapomniałeś typu, albo nie wiedziałeś, że klasa jest ogólna i ostrzeże Cię o tym.
Class<?>
Class
nie można przekazać argumentu, którego typ jest Class<?>
, więc Class<?>
jest wygodniejszy w każdej sytuacji.
To <?>
jest bestia. Często prowadzi to do nieporozumień i błędów, ponieważ gdy widzisz to najpierw, to zaczynasz wierzyć, <?>
jest to symbol wieloznaczny dla każdego typu Java . Co jest ... nieprawdą. <?>
to nieznany typ , drobna i nieprzyjemna różnica.
Nie stanowi problemu, gdy używasz go z Class
. Obie linie działają i kompilują się:
Class anyType = String.class;
Class <?> theUnknownType = String.class;
Ale - jeśli zaczniemy go używać z kolekcjami, to zobaczymy dziwne błędy w czasie kompilacji:
List<?> list = new ArrayList<Object>(); // ArrayList<?> is not allowed
list.add("a String"); // doesn't compile ...
Nasza List<?>
kolekcja nie jest odpowiednia dla każdego rodzaju przedmiotu. Może przechowywać tylko jeden typ: mistyczny „nieznany typ”. Co na pewno nie jest prawdziwym typem.
Oznacza to, że odwołanie do klasy może zawierać odwołanie do dowolnego obiektu klasy.
Zasadniczo jest to to samo, co „Class”, ale pokazujesz innym osobom, które czytają Twój kod, że nie zapomniałeś o rodzajach generycznych, potrzebujesz tylko odwołania, które może przechowywać dowolny obiekt Class.
Bruce Eckel, Thinking in Java:
W Javie SE5 klasa <?> Jest preferowana w stosunku do zwykłej klasy, mimo że są równoważne, a zwykła klasa, jak widzieliśmy, nie generuje ostrzeżenia kompilatora. Zaletą Class <?> Jest to, że wskazuje, że nie używasz niespecyficznego odwołania do klasy przez przypadek lub z powodu ignorancji. Wybrałeś niespecyficzną wersję.
To dosłowny rodzaj ogólny . Oznacza to, że nie wiesz, jaki typ klasy Class
reprezentuje ta instancja, ale nadal używasz wersji ogólnej.
Class<Foo>
. W ten sposób możesz na przykład utworzyć nową instancję bez rzutowania:Foo foo = clazz.newInstance();