Co oznacza klasa <?> W języku Java?


Odpowiedzi:


114

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


8
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.


9

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ę.


1
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)

5

W typach ogólnych nieznany typ jest reprezentowany przez symbol wieloznaczny „?”. Przeczytaj tutaj oficjalny przykład.


3

Oznacza to klasę z jakimkolwiek typem (nieznany).

Powinieneś przeczytać samouczek java generics, aby lepiej go zrozumieć

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.