2012-02-04 2 views
8

¿Cómo se compila esta sentencia de Java sin advertencias?Integer.class y int.class

Class<Integer> x = int.class; 

a pesar de que

Integer.class != int.class 

Editar: Dicho de una manera diferente, parece como si Integer.class y int.class tienen nada en común (ver comentarios abajo), así que ¿por qué tener sentido para esta asignación es posible?

+3

la declaración de 'int.class' es:' pública estática final Clase \t TYPE = (Clase ) Class.getPrimitiveClass ("int"); 'Dado que el parámetro tipo realmente no importa y está enmarcado, es pasable. – bestsss

+0

@bestsss: El valor está encuadrado pero otras propiedades de la clase no son válidas. Por ejemplo, uno puede usar la reflexión para construir un 'Entero 'usando' Entero.clasificado' pero no hay forma de hacer esto con 'int.class'. – casablanca

+0

no se puede construir un 'int' en absoluto a través de la reflexión, es una primitiva. La decisión es bastante simple: los primitivos están encuadrados, por lo que en cualquier lugar donde se pueda pasar un int, un entero haría (o viceversa). Sin embargo, hay una excepción: los parámetros de clase simples son totalmente diferentes, la reflexión como 'getMethod (" xxx ", Integer.class)' no funcionará para 'xxx (int x)'. – bestsss

Respuesta

6

Después de un montón de búsqueda, me encontré con este pequeño fragmento en el JLS, section 15.8.2 Class Literals:

Si p es el nombre de un tipo primitivo, sea B el tipo de una expresión de tipo p después de la conversión del boxeo (§5.1.7). Entonces el tipo de p.class es Clase <B>.

La especificación no explica por qué esto es así, en lugar de Class<?> por ejemplo. Tampoco he podido encontrar ninguna evidencia de que esto esté relacionado con los genéricos o el autoboxing.

Integer es un objeto de primera clase, mientras que int es un tipo primitivo, y la mayoría de los métodos de Class como isInstance, isAssignableFrom y cast que operan sobre Object s no son válidos en el contexto de int.class. En consecuencia, no veo ninguna razón por la cual el tipo de int.class es Class<Integer>.

4

Debido a autoboxing. No puede usar primitivas en forma de parámetros de tipo, por lo que la primitiva está encuadrada en el envoltorio.

+2

No veo por qué eso requeriría que el autoboxing también funcionara en los literales de clase. –

+0

Parece una solución, porque no puede tener la clase . Por supuesto, puede usar 'Clase ' – Bozho

+0

De hecho, parece un truco, y no veo ningún motivo por el que 'Clase ' no sea suficiente. Mira mi comentario anterior: 'Integer.class' y' int.class' no son ni siquiera similares a lo que cabría esperar. – casablanca

4

No creo que esto tenga nada que ver con el autoboxing.

Esto es parte de las reglas de los genéricos que trata los tipos primitivos como sus envoltorios.

+0

¿Está esto especificado en alguna parte del JLS? – casablanca

+0

Creo que sí. ;) –

Cuestiones relacionadas