¿Qué significa Clase <?> En Java?

Respuestas:

109

Classes una clase parametrizable, por lo tanto, puede usar la sintaxis Class<T>donde Tes un tipo. Al escribir Class<?>, está declarando un Classobjeto que puede ser de cualquier tipo ( ?es un comodín). El Classtipo es un tipo que contiene metainformación sobre una clase.

Siempre es una buena práctica referirse a un tipo genérico especificando su tipo específico, al usarlo Class<?>respeta esta práctica (sabe Classque es parametrizable) pero no restringe su parámetro para que tenga un tipo específico.

Referencia sobre genéricos y comodines: http://docs.oracle.com/javase/tutorial/java/generics/wildcards.html

Referencia sobre Classobjeto y reflexión (la característica del lenguaje Java utilizada para introspectarse a sí mismo): https://www.oracle.com/technetwork/articles/java/javareflection-1536171.html

manubrio
fuente
77
¿Cuál es el beneficio de hacer esto simplemente usando Classsin un tipo? Parecen representar lo mismo.
cenizas999
1
Pensé que el punto principal de un genérico es que no conoces el tipo de clase por adelantado. De lo contrario, solo definiría una función para usar un tipo de clase particular para el parámetro. Este signo de interrogación todavía no tiene sentido.
Brain2000
55
No hay otro beneficio, excepto que le está diciendo al compilador que "sé que esta es una clase genérica, pero no sé ni me importa el tipo real, así que en lugar de dar un tipo concreto, le doy el ?comodín". . Si no le da el comodín, el compilador asume que olvidó el tipo o no sabía que la clase era genérica y le advertirá al respecto.
Kayaman
1
¿Cuál es el equivalente de Kotlin?Class<?>
JGuo
simplemente Classno se puede pasar a un argumento de qué tipo es Class<?>, por lo que Class<?>es más conveniente para todas las situaciones.
petertc
72

Esta <?>es una bestia A menudo conduce a confusión y errores, porque, cuando lo ves por primera vez, comienzas a creer, <?>es un comodín para cualquier tipo de Java . Lo cual no es cierto. <?>Es el tipo desconocido , una ligera y desagradable diferencia.

No es un problema cuando lo usas con Class. Ambas líneas funcionan y compilan:

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

Pero , si comenzamos a usarlo con colecciones, entonces vemos errores extraños en tiempo de compilación:

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

La nuestra List<?>no es una colección, que es adecuada para cualquier tipo de objeto. Solo puede almacenar un tipo: el místico "tipo desconocido". Que no es un tipo real, seguro.

Andreas Dolk
fuente
8

Significa que su referencia de clase puede contener una referencia a cualquier objeto de clase.

Básicamente es lo mismo que "Clase", pero estás mostrando a otras personas que leen tu código que no te olvidaste de los genéricos, solo quieres una referencia que pueda contener cualquier objeto de Clase.

Bruce Eckel, Pensando en Java:

En Java SE5, se prefiere la clase <?> Sobre la clase simple, a pesar de que son equivalentes y la clase simple, como viste, no produce una advertencia del compilador. El beneficio de la Clase <?> Es que indica que no solo estás usando una referencia de clase no específica por accidente o por ignorancia. Elegiste la versión no específica.

Filip
fuente
1
La cita dice "Se prefiere la clase <?> Sobre la clase simple" y "El beneficio de la clase <?>". Parece que blockquote no está de acuerdo con los corchetes angulares.
Filip
1
Necesita ser escapado. Solucionado ahora: P
Sami Kuhmonen
5

Es un literal genérico . Significa que no sabe el tipo de clase que Classrepresenta esta instancia, pero todavía está utilizando la versión genérica.

  • si conocieras la clase, la usarías Class<Foo>. De esa manera, puede crear una nueva instancia, por ejemplo, sin emitir:Foo foo = clazz.newInstance();
  • si no usa genéricos en absoluto, recibirá una advertencia al menos (y no se recomienda usar genéricos, ya que puede provocar efectos secundarios difíciles de detectar)
Bozho
fuente
5

En genéricos, un tipo desconocido está representado por el carácter comodín "?". Lea aquí para ver un ejemplo oficial.

Jasonw
fuente
3

Eso significa una clase con un tipo de cualquier cosa (desconocida).

Deberías leer el tutorial de genéricos de Java para entenderlo mejor

fmucar
fuente