Pregunta

Por lo general, el compilador genera código para realizar el boxeo y unboxing. Pero lo que hace el compilador, si no son necesarios los valores en caja? ¿Está el (Oracle estándar) compilador lo suficientemente inteligente como para optimizar la basura?

Tome un vistazo a este método:

public static void requireInRange(int index, Object[] array) {
    if(index < 0 || index >= array.length)
        throw new IndexOutOfBoundsException();
}

La información sólo es relevante es la array.length, por lo que sería inútil a la caja de cada valor de una matriz, por ejemplo. Al igual que en este código:

int[] anArray = {3, 4, 2};
requireInRange(3, anArray);

¿El compilador realidad inserción de código para el boxeo cada valor de la matriz?

¿Fue útil?

Solución

No hay autoboxing en el código. De hecho, teniendo en cuenta:

public static void requireInRange(int index, Object[] array) {
   ...
}

int[] anArray = {3, 4, 2};
requireInRange(3, anArray); // DOES NOT COMPILE!!!

Mientras que un int puede autoboxed a un Integer, un int[] hace no get autoboxed a Integer[] por Java. Puede escribir funciones de biblioteca para hacer esto, pero el lenguaje no facilitar esta conversión.

Esto es de hecho la fuente de muchos confusión con respecto a, por ejemplo, Arrays.asList(anIntArray) está "roto", porque en lugar de devolver un List<Integer>, lo que se devuelve es de hecho una List<int[]> de un elemento.


¿Pero qué sobre el rendimiento ???

Una cita de Guía del lenguaje Java / Autoboxing :

  

No es apropiado utilizar autoboxing y unboxing para la computación científica, u otro código numérico sensibles al rendimiento. Un Integer no es un sustituto para un int; autoboxing y el desenfoque unboxing la distinción entre tipos primitivos y los tipos de referencia, pero no lo eliminan.

En resumen, cada vez que autoboxing sucede, el rendimiento definitivamente se necesita un poco de un golpe. Ciertas cosas ayuda a aliviar este, por ejemplo, el mecanismo de caché integrada en estos tipos. Es por esto que se obtiene lo siguiente:

    System.out.println(
        ((Integer) 0) == ((Integer) 0)
    );
    // true

    System.out.println(
        ((Integer) 10000) == ((Integer) 10000)
    );
    // false (implementation-specific)

Lo que pasó aquí es que cuando 0 es automáticamente en caja, sin nueva ejemplo Integer se crea realmente: los valores en cierto rango es caché para autoboxing propósitos, con el desempeño de ayuda. 10000 en la mayor aplicación probablemente cae fuera de este rango, pero algunas implementaciones de JVM hacer le permiten especificar el rango de caché si es necesario.


Pero sólo quiero obtener la longitud de la matriz !!!

Hay muchas maneras de facilitar su requireInRange para trabajar con cualquier tipo de matrices. Desafortunadamente trabajar con conjunto de primitivas de Java a menudo significa un montón de repetición. Esto significa que debe ofrecer sobrecargas para int[], boolean[], byte[], Object[], etc por separado.

Una opción más concisa es utilizar la reflexión, pero esto tiene sus ventajas y desventajas. En términos generales, la reflexión no debe ser la solución preferida para la mayoría de los escenarios.

Una vez dicho esto, java.lang.reflect.Array tiene un int getLength(Object array) static método que puede devolver la longitud de CUALQUIER array. No es typesafe (como la mayoría mecanismo de reflexión son); pasando una compila no matriz, pero lanza IllegalArgumentException en tiempo de ejecución.

preguntas relacionadas

Otros consejos

  

cifrará el compilador realmente inserto   para el boxeo cada valor de la matriz?

El compilador rechazará el código porque un int[] no se puede pasar en un método que toma un parámetro Object[].

Autoboxing sucede sólo para valores primitivos individuales, no para las matrices enteras.

En caso de duda, se puede asumir que el compilador no optimizar el código. Generalmente se hace una traducción literal del código.

Además, en caso de duda youc una suponer la JVM hace un muy buen trabajo de optimización de código en tiempo de ejecución. Yo no asuma que hace ninguna diferencia a menos que tenga una buena razón (tal como perfilador) para sospechar que es un problema.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top