2012-03-29 15 views
83

Frage wie oben, tut mir leid, es ist wahrscheinlich ein Duplikat, aber ich konnte kein Beispiel mit dem <?> am Ende finden.Was bedeutet Klasse <?> in Java?

Warum würden Sie nicht einfach Class als Parameter verwenden?

+0

http://en.wikipedia.org/wiki/Wildcard_%28Java%29 – Anycorn

+0

http://stackoverflow.com/q/2024513/1140748 –

Antwort

67

Class ist eine parametrisierbare Klasse, daher können Sie die Syntax verwenden Class<T> wobei T ein Typ ist. Indem Sie Class<?> schreiben, deklarieren Sie ein Class Objekt, das von jedem Typ sein kann (? ist ein Platzhalter). Der Typ Class ist ein Typ, der Metainformationen zu einer Klasse enthält.

Es ist immer ratsam, auf eine generische Art zu beziehen, die durch seine spezifische Art Angabe von Class<?> verwenden Sie diese Praxis sind zu respektieren (du bist bewusst Class zu sein parametrisierbare), aber Sie beschränken nicht Ihre Parameter zu haben, ein bestimmter Typ

Referenz über Generics und Wildcards: http://docs.oracle.com/javase/tutorial/java/generics/wildcards.html

Referenz über Klassenobjekt und Reflexion (das Merkmal der Java-Sprache verwendet, sich selbst zu überwachen): http://java.sun.com/developer/technicalArticles/ALT/Reflection/

+3

Was ist der Vorteil, dies zu tun, indem einfach 'Class' ohne Typ verwendet wird? Sie scheinen dasselbe darzustellen. – ashes999

+0

Ich dachte, der ganze Sinn eines Generics ist, dass Sie den Klassentyp im Voraus nicht kennen. Andernfalls würden Sie einfach eine Funktion definieren, um einen bestimmten Klassentyp für den Parameter zu verwenden. Dieses Fragezeichen macht immer noch keinen Sinn. – Brain2000

+2

Es gibt keinen anderen Vorteil, außer dass Sie dem Compiler sagen: "Ich weiß, dass dies eine generische Klasse ist, aber ich weiß nicht, ob der eigentliche Typ wichtig ist oder nicht. 'Wildcard.". Wenn Sie den Platzhalter nicht angeben, geht der Compiler davon aus, dass Sie entweder den Typ vergessen haben oder nicht wussten, dass die Klasse generisch ist und Sie davor warnen. – Kayaman

5

Es ist ein generics Literal. Das bedeutet, dass Sie den Typ der Klasse nicht kennen, die diese Class Instanz darstellt, aber Sie verwenden immer noch die generische Version.

  • Wenn Sie die Klasse kennen würden, würden Sie Class<Foo> verwenden. Auf diese Weise können Sie eine neue Instanz erstellen, zum Beispiel ohne Casting: Foo foo = clazz.newInstance();
  • Wenn Sie Generika überhaupt nicht verwenden, erhalten Sie mindestens eine Warnung (und Generika werden im Allgemeinen nicht empfohlen, da dies zu einem Fehler führen kann schwer zu erkennende Nebeneffekte)
2

Das bedeutet eine Klasse mit einem Typ von irgendetwas (unbekannt).

Sie sollten Java Generics Tutorial lesen, um es besser zu verstehen

5

Es bedeutet, dass Ihre Klasse Verweis einen Verweis auf eine Klasse-Objekt enthalten kann.

Es ist im Grunde das gleiche wie "Klasse", aber Sie zeigen anderen Menschen, die Ihren Code lesen, dass Sie Generika nicht vergessen haben, Sie wollen nur eine Referenz, die jedes Klassenobjekt enthalten kann.

Bruce Eckel, Denken in Java:

In Java SE5, Klasse <> über Normal Klasse bevorzugt, obwohl sie gleichwertig sind und die Ebene der Klasse, wie Sie gesehen haben, nicht produzieren? eine Compiler-Warnung. Der Vorteil der Klasse <?> Ist, dass es angibt, dass Sie nicht nur eine unspezifische Klassenreferenz von Unfall oder aus Unwissenheit verwenden. Sie haben die unspezifische Version gewählt.

+1

Das Zitat sagt: "Klasse über Normal Klasse bevorzugt wird" und „The Vorteil der Klasse ". Es scheint, dass blockquote nicht mit den eckigen Klammern übereinstimmt. – MasterF

+0

Es muss entgangen werden. Es wurde jetzt behoben: P –

3

In Generika, ein unbekannter Typ wird durch das Wildcard-Zeichen dargestellt "?" Lesen Sie here für offizielles Beispiel.

42

Diese <?> ist ein Biest.Es führt oft zu Verwirrung und Fehlern, denn wenn Sie es zuerst sehen, dann beginnen Sie zu glauben, <?> ist ein Platzhalter für jeder Java-Typ. Was nicht wahr ist. <?> ist der unbekannte Typ, ein leichter und ekliger Unterschied.

Es ist kein Problem, wenn Sie es mit Class verwenden. Beide Linien arbeiten und kompilieren:

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

Aber - wenn wir die Verwendung mit einer Sammlung zu starten, dann sehen wir, seltsam compiletime Fehler:

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

Unsere List<?> ist nicht eine Sammlung, die geeignet ist, für jede Art von Objekt. Es kann nur einen Typ speichern: den mystischen "unbekannten Typ". Was sicher kein echter Typ ist.