java casting java-7 unboxing

Diferencias en el auto-unboxing entre Java 6 vs Java 7



casting java-7 (2)

Parece que el lenguaje de la sección 5.5 Conversión de conversión de Java 7 JLS se actualizó en comparación con la misma sección en Java 5/6 JLS , probablemente para aclarar las conversiones permitidas.

Java 7 JLS dice

Una expresión de un tipo de referencia puede experimentar una conversión de conversión a un tipo primitivo sin error, mediante la conversión de unboxing.

Java 5/6:

Un valor de un tipo de referencia puede convertirse a un tipo primitivo mediante la conversión de unboxing (§5.1.8).

Java 7 JLS también contiene una tabla (tabla 5.1) de conversiones permitidas (esta tabla no está incluida en Java 5/6 JLS) de tipos de referencia a primitivos. Esto enumera explícitamente los moldes de Object a primitivos como una conversión de referencia de estrechamiento con unboxing.

El motivo se explica en este correo electrónico :

En resumen: si la especificación. permite (Objeto) (int) también debe permitir (int) (Objeto).

He notado una diferencia en el comportamiento de unboxing automático entre Java SE 6 y Java SE 7. Me pregunto por qué es así, porque no puedo encontrar ninguna documentación de cambios en este comportamiento entre estas dos versiones.

Aquí hay un ejemplo simple:

Object[] objs = new Object[2]; objs[0] = new Integer(5); int myInt = (int)objs[0];

Esto compila bien con javac de Java SE 7. Sin embargo, si le doy al compilador el argumento "-source 1.6", aparece un error en la última línea:

inconvertible types found : java.lang.Object required: int

Traté de descargar Java SE 6 para compilar con el compilador nativo de la versión 6 (sin ninguna opción de fuente). Acepta y da el mismo error que el anterior.

Entonces, ¿qué da? A partir de un poco más de experimentación, parece que el desempaquetado en Java 6 solo puede desunir los valores que claramente (en tiempo de compilación) son del tipo de recuadro. Por ejemplo, esto funciona en ambas versiones:

Integer[] objs = new Integer[2]; objs[0] = new Integer(5); int myInt = (int)objs[0];

Así que parece que entre Java 6 y 7, la característica de unboxing se mejoró para que pudiera lanzar y desempaquetar tipos de objetos en un solo golpe, sin saber (en tiempo de compilación) que el valor es del tipo apropiado. Sin embargo, al leer la Especificación del lenguaje Java o las publicaciones en el blog que se escribieron en el momento en que apareció Java 7, no veo ningún cambio en esto, así que me pregunto cuál es el cambio y cómo se llama esta "función" ?

Solo una curiosidad: debido al cambio, es posible activar unboxings "incorrectos":

Object[] objs = new Float[2]; objs[0] = new Float(5); int myInt = (int)objs[0];

Esto compila bien, pero da una ClassCastException en tiempo de ejecución.

Cualquier referencia sobre esto?


Tienes razón; para decirlo más simple:

Object o = new Integer(1234); int x = (int) o;

Esto funciona en Java 7, pero da un error de compilación en Java 6 y siguientes. Extrañamente, esta característica no está documentada de manera prominente; por ejemplo, no se menciona here . Es discutible si se trata de una nueva característica o una corrección de errores (¿o un nuevo error?), Vea alguna información relacionada y discusión . El consenso parece apuntar a una ambigüedad en la especificación original, que condujo a una implementación ligeramente incorrecta / inconsistente en Java 5/6, que se corrigió en 7, porque era fundamental para la implementación de JSR 292 (Lenguajes de tipo dinámico).

El autoboxing de Java ahora tiene más trampas y sorpresas. Por ejemplo

Object obj = new Integer(1234); long x = (long)obj;

compilará, pero fallará (con ClassCastException ) en tiempo de ejecución. Esto, en cambio, funcionará:

long x = (long)(int)obj;