Que signifie la classe <?> En Java?

Réponses:

109

Classest une classe paramétrable, vous pouvez donc utiliser la syntaxe Class<T>Test un type. En écrivant Class<?>, vous déclarez un Classobjet qui peut être de n'importe quel type ( ?est un caractère générique). Le Classtype est un type qui contient des méta-informations sur une classe.

C'est toujours une bonne pratique de faire référence à un type générique en spécifiant son type spécifique, en utilisant Class<?>vous respectez cette pratique (vous savez Classqu'elle est paramétrable) mais vous ne limitez pas votre paramètre à un type spécifique.

Référence sur les génériques et les caractères génériques: http://docs.oracle.com/javase/tutorial/java/generics/wildcards.html

Référence sur l' Classobjet et la réflexion (la fonctionnalité du langage Java utilisée pour s'introspecter): https://www.oracle.com/technetwork/articles/java/javareflection-1536171.html

manub
la source
7
Quel est l'avantage de faire cela par rapport à une simple utilisation Classsans type? Ils semblent représenter la même chose.
ashes999
1
Je pensais que tout l'intérêt d'un générique est que vous ne connaissez pas le type de classe à l'avance. Sinon, vous définiriez simplement une fonction pour utiliser un type de classe particulier pour le paramètre. Ce point d'interrogation n'a toujours pas de sens.
Brain2000
5
Il n'y a aucun autre avantage, sauf que vous dites au compilateur que "je sais que c'est une classe générique, mais je ne connais pas ou ne me soucie pas du type réel, donc au lieu de donner un type concret, je donne le ?caractère générique." . Si vous ne donnez pas le caractère générique, le compilateur suppose que vous avez oublié le type ou que vous ne saviez pas que la classe était générique et vous en avertira.
Kayaman
1
Quel est l'équivalent Kotlin deClass<?>
JGuo
Classne peut tout simplement pas être passé à un argument dont le type est Class<?>, donc Class<?>est plus pratique pour toutes les situations.
petertc
72

C'est <?>une bête. Cela conduit souvent à de la confusion et des erreurs, car, lorsque vous le voyez en premier, vous commencez à croire, <?>c'est un caractère générique pour tout type Java . Ce qui n'est pas vrai. <?>est le type inconnu , une légère et méchante différence.

Ce n'est pas un problème lorsque vous l'utilisez avec Class. Les deux lignes fonctionnent et compilent:

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

Mais - si nous commençons à l'utiliser avec des collections, nous voyons d'étranges erreurs de compilation:

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

Notre List<?>n'est pas une collection, qui convient à n'importe quel type d'objet. Il ne peut stocker qu'un seul type: le mystique "type inconnu". Ce qui n'est pas un vrai type, bien sûr.

Andreas Dolk
la source
8

Cela signifie que votre référence de classe peut contenir une référence à n'importe quel objet de classe.

C'est fondamentalement la même chose que "Class" mais vous montrez à d'autres personnes qui lisent votre code que vous n'avez pas oublié les génériques, vous voulez juste une référence qui peut contenir n'importe quel objet Class.

Bruce Eckel, Penser à Java:

Dans Java SE5, la classe <?> Est préférée à la classe ordinaire, même si elles sont équivalentes et que la classe simple, comme vous l'avez vu, ne produit pas d'avertissement du compilateur. L'avantage de la classe <?> Est qu'elle indique que vous n'utilisez pas simplement une référence de classe non spécifique par accident ou par ignorance. Vous avez choisi la version non spécifique.

Filip
la source
1
La citation dit "La classe <?> Est préférable à la classe ordinaire" et "L'avantage de la classe <?>". Il semble que blockquote ne soit pas d'accord avec les crochets angulaires.
Filip
1
Il doit être échappé. Corrigé maintenant: P
Sami Kuhmonen
5

C'est un littéral générique . Cela signifie que vous ne connaissez pas le type de classe que cette Classinstance représente, mais que vous utilisez toujours la version générique.

  • si vous connaissiez la classe, vous utiliseriez Class<Foo>. De cette façon, vous pouvez créer une nouvelle instance, par exemple, sans cast:Foo foo = clazz.newInstance();
  • si vous n'utilisez pas du tout de génériques, vous recevrez au moins un avertissement (et ne pas utiliser de génériques est généralement déconseillé car cela peut entraîner des effets secondaires difficiles à détecter)
Bozho
la source
5

Dans les génériques, un type inconnu est représenté par le caractère générique "?". Lisez ici pour un exemple officiel.

Jasonw
la source
3

Cela signifie une classe avec un type de n'importe quoi (inconnu).

Vous devriez lire le didacticiel Java Generics pour mieux le comprendre

fmucar
la source