Что означает Class <?> В Java?


136

Мой вопрос такой же, как указано выше. Извините, вероятно, это дубликат, но я не смог найти пример со знаком <?>на конце.

Почему бы вам просто не использовать Classв качестве параметра?



Ответы:


109

Classявляется параметризуемым классом, поэтому вы можете использовать синтаксис, Class<T>где T- тип. Написав Class<?>, вы объявляете Classобъект, который может быть любого типа ( ?подстановочный знак). ClassЯвляется тип , который содержит мета-информацию о классе.

Всегда полезно ссылаться на общий тип, указав его конкретный тип, используя Class<?>вы соблюдаете эту практику (вы знаете, Classчто это параметризуемый), но вы не ограничиваете свой параметр определенным типом.

Ссылка на обобщения и подстановочные знаки: http://docs.oracle.com/javase/tutorial/java/generics/wildcards.html

Справка об Classобъекте и отражении (функция языка Java, используемая для самоанализа): https://www.oracle.com/technetwork/articles/java/javareflection-1536171.html


7
В чем преимущество этого по сравнению с простым использованием Classбез типа? Кажется, они представляют одно и то же.
ashes999

1
Я думал, что весь смысл универсального в том, что вы заранее не знаете тип класса. В противном случае вы бы просто определили функцию для использования определенного типа класса для параметра. Этот вопросительный знак по-прежнему не имеет смысла.
Brain2000 06

5
Других преимуществ нет, кроме того, что вы говорите компилятору: «Я знаю, что это общий класс, но я не знаю и не забочусь о фактическом типе, поэтому вместо того, чтобы указывать конкретный тип, я даю ?подстановочный знак». , Если вы не укажете подстановочный знак, компилятор предполагает, что вы либо забыли тип, либо не знали, что класс является универсальным, и предупредит вас об этом.
Kayaman

1
Что такое Котлинский эквивалентClass<?>
JGuo

просто Classнельзя перейти к аргументу, тип которого есть Class<?>, так Class<?>что удобнее для всей ситуации.
petertc 05

72

Это <?>зверь. Это часто приводит к путанице и ошибкам, потому что, когда вы сначала видите это, то начинаете верить, <?>что это подстановочный знак для любого типа java . Что .. неправда. <?>это неизвестный тип , небольшая и неприятная разница.

Это не проблема, когда вы используете его с Class. Обе строки работают и компилируются:

Class anyType = String.class;
Class <?> theUnknownType = String.class;

Но - если мы начнем использовать его с коллекциями, то увидим странные ошибки времени компиляции:

List<?> list = new ArrayList<Object>();  // ArrayList<?> is not allowed
list.add("a String");                    // doesn't compile ...

Наша List<?>коллекция не подходит для любого типа объекта. Он может хранить только один тип: мистический «неизвестный тип». Который, конечно, не настоящий тип.


8

Это означает, что ваша ссылка на класс может содержать ссылку на любой объект класса.

Это в основном то же самое, что и «Класс», но вы показываете другим людям, которые читают ваш код, что вы не забыли о дженериках, вам просто нужна ссылка, которая может содержать любой объект класса.

Брюс Экель, мышление на Java:

В Java SE5 класс <?> Предпочтительнее простого класса, даже если они эквивалентны, а простой класс, как вы видели, не выдает предупреждения компилятора. Преимущество Class <?> Состоит в том, что он указывает на то, что вы не случайно или по незнанию используете неспецифическую ссылку на класс. Вы выбрали неконкретную версию.


1
В цитате говорится: «Класс <?> Предпочтительнее простого класса» и «Преимущество класса <?>». Кажется, цитата не согласуется с угловыми скобками.
Филип

1
Этого нужно избежать. Исправлено: P
Сами Кухмонен

5

Это литерал дженериков . Это означает, что вы не знаете тип класса, Classкоторый представляет этот экземпляр, но вы все еще используете общую версию.

  • если бы вы знали класс, вы бы использовали Class<Foo>. Таким образом вы можете создать новый экземпляр, например, без приведения:Foo foo = clazz.newInstance();
  • если вы вообще не используете дженерики, вы получите как минимум предупреждение (и не использовать дженерики, как правило, не рекомендуется, поскольку это может привести к трудно обнаруживаемым побочным эффектам)

5

В дженериках неизвестный тип представлен подстановочным знаком «?». Прочтите здесь официальный пример.


3

Это означает класс с каким-либо типом (неизвестным).

Вы должны прочитать руководство по java generics, чтобы лучше понять его

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.