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.
Jaka jest korzyść z robienia tego w porównaniu z prostym używaniem Classbez typu? Wydają się reprezentować to samo.
popioły 999
1
Pomyślałem, że głównym celem generycznych jest to, że nie znasz z góry typu klasy. W przeciwnym razie wystarczy zdefiniować funkcję, która będzie używać określonego typu klasy dla parametru. Ten znak zapytania nadal nie ma sensu.
Brain2000
7
Nie ma żadnej innej korzyści poza tym, że powiesz kompilatorowi, że „Wiem, że jest to klasa ogólna, ale nie znam ani nie obchodzi mnie, jaki jest rzeczywisty typ, więc zamiast podawać konkretny typ, podaję ?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.
Kayaman
1
Jaki jest odpowiednik KotlinaClass<?>
Jack Guo
po prostu Classnie można przekazać argumentu, którego typ jest Class<?>, więc Class<?>jest wygodniejszy w każdej sytuacji.
petertc
76
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ę.
Cytat mówi „Klasa <?> Jest preferowana w stosunku do zwykłej klasy” i „Korzyść z klasy <?>”. Wygląda na to, że cytat blokowy nie zgadza się z nawiasami kątowymi.
Filip
1
Trzeba uciec. Naprawiono to teraz: P
Sami Kuhmonen
5
To dosłowny rodzaj ogólny . Oznacza to, że nie wiesz, jaki typ klasy Classreprezentuje ta instancja, ale nadal używasz wersji ogólnej.
gdybyś znał klasę, użyłbyś Class<Foo>. W ten sposób możesz na przykład utworzyć nową instancję bez rzutowania:Foo foo = clazz.newInstance();
jeśli w ogóle nie używasz leków generycznych, otrzymasz przynajmniej ostrzeżenie (a niestosowanie leków generycznych jest generalnie odradzane, ponieważ może to prowadzić do trudnych do wykrycia skutków ubocznych)
Odpowiedzi:
Class
jest klasą parametryzowalną, dlatego możesz użyć składni,Class<T>
gdzieT
jest typem. PiszącClass<?>
, deklarujeszClass
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ś świadomyClass
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źródło
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 jestClass<?>
, więcClass<?>
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ę: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.źródło
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:
źródło
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();
źródło
W typach ogólnych nieznany typ jest reprezentowany przez symbol wieloznaczny „?”. Przeczytaj tutaj oficjalny przykład.
źródło
Oznacza to klasę z jakimkolwiek typem (nieznany).
Powinieneś przeczytać samouczek java generics, aby lepiej go zrozumieć
źródło