Pregunta

Es allí cualquier sobrecarga cuando echamos a los objetos de un tipo a otro?O el compilador sólo resuelve todo y no hay ningún costo en tiempo de ejecución?

Es este un general de las cosas, o hay diferentes casos?

Por ejemplo, supongamos que tenemos un array de Object[], donde cada elemento puede tener un tipo diferente.Pero siempre tenemos la certeza de que, digamos, el elemento 0 es un Doble, el elemento 1 es una Cadena.(Sé que esto es un mal diseño, pero vamos a asumir que tenía que hacer esto.)

Java es el tipo de información que aún se mantenía alrededor en tiempo de ejecución?O todo está olvidado después de la compilación, y si hacemos (Doble)elementos[0], sólo tendremos que seguir el puntero e interpretar los 8 bytes como un doble, lo que es?

Estoy muy claro acerca de cómo los tipos se hace en Java.Si usted tiene cualquier reccommendation en los libros o en el artículo a continuación, gracias, también.

¿Fue útil?

Solución

Hay 2 tipos de casting:

Implícito casting, cuando se convierte de un tipo a un amplio tipo, que se realiza automáticamente y no hay sobrecarga:

String s = "Cast";
Object o = s; // implicit casting

Explícito casting, cuando usted vaya a un amplio tipo a un más estrecho.Para este caso, debe utilizar explícitamente la fundición como que:

Object o = someObject;
String s = (String) o; // explicit casting

En este segundo caso, se produce una sobrecarga en tiempo de ejecución, debido a que los dos tipos deben ser revisados y en caso de que la conversión no es factible, JVM debe lanzar una ClassCastException.

Tomado de JavaWorld:El costo de la fundición

Casting se utiliza para convertir entre tipos, entre los tipos de referencia en en particular, para el tipo de fundición operación en la que estamos interesados aquí.

Upcast operaciones (también llamado las conversiones de ampliación en Java La Especificación del lenguaje) convertir un subclase referencia a un antepasado referencia de la clase.Este casting la operación es normalmente automática, ya siempre es seguro y puede ser realizados directamente por el compilador.

Abatido operaciones (también llamado las conversiones de restricción en Java La Especificación del lenguaje) convertir un de la clase padre referencia a una subclase de referencia.Esta operación de fundición crea la ejecución de sobrecarga, ya que Java requiere que el reparto de ser revisada en tiempo de ejecución para asegurarse de que es válido.Si el objeto de referencia no es un ejemplo de el tipo de destino para el yeso o una subclase de ese tipo, el intento de conversión no es permitido y debe de tirar java.lang.ClassCastException.

Otros consejos

Para una aplicación razonable de Java:

Cada objeto tiene una cabecera que contiene, entre otras cosas, un puntero al tipo de tiempo de ejecución (por ejemplo Double o String, pero podría no ser CharSequence o AbstractList). Suponiendo que el tiempo de ejecución del compilador (generalmente HotSpot en el caso de Sun) no puede determinar el tipo estáticamente a algunas de las necesidades comprobación que se han realizado por el código de máquina generado.

En primer lugar ese puntero a las necesidades de tipo en tiempo de ejecución para ser leído. Esto es necesario para llamar a un método virtual en una situación similar de todos modos.

Para la fundición de un tipo de clase, se sabe exactamente cuántos superclases que hay hasta llegar a java.lang.Object, por lo que el tipo se puede leer en un desplazamiento del puntero de tipo (en realidad los ocho primeros en HotSpot) constante. De nuevo, esto es análogo a la lectura de un puntero método para un método virtual.

A continuación, el valor de lectura sólo necesita una comparación con el tipo estático esperada del elenco. Dependiendo de la arquitectura del conjunto de instrucciones, otra instrucción necesitará rama (o fallo) en una rama incorrecta. NIA como ARM de 32 bits tienen instrucción condicional y puede ser capaz de tener la ruta pase triste a través del camino feliz.

Interfaces son más difíciles debido a la herencia múltiple de interfaz. En general, los dos últimos moldes a las interfaces se almacenan en caché en el tipo de ejecución. En los primeros días (hace más de una década), las interfaces eran un poco lento, pero que ya no es relevante.

Con suerte se puede ver que este tipo de cosas es en gran medida irrelevante para el rendimiento. Su código fuente es más importante. En términos de rendimiento, el mayor éxito en su escenario es susceptible de ser errores de caché de perseguir a los punteros a objetos por todo el lugar (la información de tipo, por supuesto, ser común).

  

Por ejemplo, supongamos que tenemos una serie de Object [], donde cada elemento puede tener un tipo diferente. Pero siempre sabemos con seguridad que, por ejemplo, el elemento 0 es un doble, 1 elemento es una cadena. (Sé que esto es un mal diseño, pero vamos a suponer que tenía que hacer esto.)

El compilador no tenga en cuenta los tipos de los elementos individuales de una matriz. Es simplemente comprueba que el tipo de cada elemento expresión es asignable al tipo de elemento de matriz.

  

información de tipo de es Java todavía mantiene entorno en tiempo de ejecución? O todo se olvida después de la compilación, y si lo hacemos (Doble) elementos [0], que sólo va a seguir el puntero e interpretar esos 8 bytes como un doble, sea lo que sea?

Parte de la información se mantiene en torno al tiempo de ejecución, pero no los tipos estáticos de los elementos individuales. Se puede decir esto de mirar el formato de archivo de clase.

Es teóricamente posible que el compilador JIT podría usar "análisis de escape" para eliminar los controles de tipo innecesarias en algunas tareas. Sin embargo, hacer esto en la medida en que está sugiriendo estaría más allá de los límites de optimización realista. La recompensa de analizar los tipos de elementos individuales sería demasiado pequeño.

Además, las personas código de la aplicación no se debe escribir como eso de todos modos.

El código de bytes de instrucciones para realizar la fundición en tiempo de ejecución se llama checkcast. Puede desensamblar el código Java usando javap para ver lo que se generan instrucciones.

Para las matrices, Java mantiene información de tipo en tiempo de ejecución. La mayoría de las veces, el compilador detectará errores de tipo para usted, pero hay casos en los que se ejecutará en un ArrayStoreException cuando se trata de almacenar un objeto en una matriz, pero el tipo no coincide (y el compilador no se contagió ). El Java especificación lenguaje da el siguiente ejemplo:

class Point { int x, y; }
class ColoredPoint extends Point { int color; }
class Test {
    public static void main(String[] args) {
        ColoredPoint[] cpa = new ColoredPoint[10];
        Point[] pa = cpa;
        System.out.println(pa[1] == null);
        try {
            pa[0] = new Point();
        } catch (ArrayStoreException e) {
            System.out.println(e);
        }
    }
}

Point[] pa = cpa es válido, ya que ColoredPoint es una subclase de punto, pero pa[0] = new Point() no es válido.

Esto se opone a los tipos genéricos, donde no hay información de tipo guardado en tiempo de ejecución. Los insertos compilador checkcast instrucciones cuando sea necesario.

Esta diferencia en la tipificación de los tipos genéricos y matrices de manera que suele ser inadecuada para mezclar las matrices y tipos genéricos.

En teoría, no se introduce sobrecarga. Sin embargo, las JVM modernas son inteligentes. Cada aplicación es diferente, pero no es razonable suponer que podría existir una implementación que JIT optimizado de distancia fundición cheques cuando se podía garantizar que nunca habría un conflicto. En cuanto a qué JVM específicos ofrecen esto, yo no podría decir. Debo admitir que me gustaría conocer los detalles de la optimización JIT a mí mismo, pero estos son para los ingenieros de JVM que preocuparse.

La moraleja de la historia es que escribir código entendible por primera vez. Si usted está experimentando desaceleraciones, perfil e identificar su problema. Las probabilidades son buenas que no va a ser debido a la fundición. Nunca sacrifique un código limpio, seguro en un intento de optimizar hasta que sabe que necesita.

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