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 Classjako 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 Classjako parametru?
Odpowiedzi:
Classjest klasą parametryzowalną, dlatego możesz użyć składni, Class<T>gdzie Tjest typem. Pisząc Class<?>, deklarujesz Classobiekt, który może być dowolnego typu ( ?jest to symbol wieloznaczny). ClassTyp 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 Classmoż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 Classobiekcie i odbiciu (funkcja języka Java używana do introspekcji): https://www.oracle.com/technetwork/articles/java/javareflection-1536171.html
Classbez 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<?>
Classnie 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 Classreprezentuje 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();