O que significa Classe <?> Em Java?

Respostas:

109

Classé uma classe parametrizável, portanto, você pode usar a sintaxe Class<T>onde Té um tipo. Ao escrever Class<?>, você está declarando um Classobjeto que pode ser de qualquer tipo ( ?é um curinga). O Classtipo é um tipo que contém meta-informações sobre uma classe.

É sempre uma boa prática se referir a um tipo genérico, especificando o tipo específico dele, usando Class<?>você está respeitando essa prática (você sabe Classque é parametrizável), mas você não está restringindo seu parâmetro a um tipo específico.

Referência sobre genéricos e curingas: http://docs.oracle.com/javase/tutorial/java/generics/wildcards.html

Referência sobre Classobjeto e reflexão (o recurso da linguagem Java usado para se introspectar): https://www.oracle.com/technetwork/articles/java/javareflection-1536171.html

manub
fonte
7
Qual é o benefício de fazer isso simplesmente usando Classsem um tipo? Eles parecem representar a mesma coisa.
ashes999
1
Eu pensei que o ponto principal de um genérico é que você não conhece o tipo de classe antecipadamente. Caso contrário, você apenas definiria uma função para usar um tipo de classe específico para o parâmetro. Este ponto de interrogação ainda não faz sentido.
Brain2000
5
Não há outro benefício, a não ser que você esteja dizendo ao compilador que "eu sei que essa é uma classe genérica, mas não sei nem me importo com o tipo real, então, em vez de dar um tipo concreto, estou dando o ?curinga". . Se você não fornecer o curinga, o compilador assume que você esqueceu o tipo ou não sabia que a classe era genérica e o alertará sobre isso.
21416 Kayaman
1
Qual é o equivalente de KotlinClass<?>
JGuo
simplesmente Classnão pode ser passado para um argumento que tipo é Class<?>, então Class<?>é mais conveniente para todas as situações.
precisa saber é
72

Isso <?>é uma fera. Isso geralmente gera confusão e erros, porque, quando você o vê pela primeira vez e começa a acreditar, <?>é um curinga para qualquer tipo de java . O que não é verdade. <?>é o tipo desconhecido , uma diferença leve e desagradável.

Não é um problema quando você o usa Class. Ambas as linhas funcionam e compilam:

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

Mas - se começarmos a usá-lo com coleções, veremos erros estranhos de compilação:

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

Nossa List<?>coleção não é adequada para qualquer tipo de objeto. Só pode armazenar um tipo: o místico "tipo desconhecido". O que não é do tipo real, com certeza.

Andreas Dolk
fonte
8

Isso significa que sua referência de classe pode conter uma referência a qualquer objeto de classe.

É basicamente o mesmo que "Class", mas você está mostrando a outras pessoas que leem seu código que não esqueceu os genéricos, apenas deseja uma referência que possa conter qualquer objeto de Class.

Bruce Eckel, Pensando em Java:

No Java SE5, a classe <?> É preferida à classe simples, mesmo que sejam equivalentes e a classe simples, como você viu, não produz um aviso do compilador. O benefício da classe <?> É que indica que você não está apenas usando uma referência de classe não específica por acidente ou por ignorância. Você escolheu a versão não específica.

Filip
fonte
1
A citação diz "A classe <?> É preferível à classe simples" e "O benefício da classe <?>". Parece que o blockquote não concorda com os colchetes angulares.
Filip
1
Ele precisa ser escapado. Corrigido agora: P
Sami Kuhmonen 29/02
5

É um literal genérico . Isso significa que você não sabe o tipo de classe que esta Classinstância está representando, mas ainda está usando a versão genérica.

  • se você conhecesse a classe, usaria Class<Foo>. Dessa forma, você pode criar uma nova instância, por exemplo, sem transmissão:Foo foo = clazz.newInstance();
  • se você não usar genéricos, receberá um aviso pelo menos (e não usar genéricos geralmente é desencorajado, pois pode levar a efeitos colaterais difíceis de detectar)
Bozho
fonte
5

Em genéricos, um tipo desconhecido é representado pelo caractere curinga "?". Leia aqui para um exemplo oficial.

Jasonw
fonte
3

Isso significa uma classe com um tipo de coisa (desconhecida).

Você deve ler o tutorial sobre genéricos em java para entender melhor

fmucar
fonte