2011-08-12 14 views
5

En Java necesitamos fundición al convertir doble (doble en el tamaño de la memoria) a entero (más pequeño en tamaño de la memoria)¿Por qué la dirección de fundición es grande o pequeña en tipos primitivos y de pequeño a grande con objetos?

int x = (int) 4.3; 

Pero en el caso de los objetos, si la clase padre es "mamífero" (pequeño tamaño de la memoria) y su subclase es "Human" (grande en tamaño de la memoria ya que tiene más propiedades entonces mamífero)

entonces

Mammal m = new Human(); //works without casting 

pero pequeño a grande conversión

Human h = (Human) m ; // needs casting 

Gracias de antemano.

+7

No debería pensar en objetos en términos de tamaño de memoria, sino en términos de lo que representan. – Jacob

Respuesta

6

La fundición no tiene que ver con el tamaño del objeto: se trata del rango de la variable.

Por 'rango', me refiero a la variedad de valores diferentes que la variable puede contener. Si asigna de una variable a otra cuyo rango es un superconjunto de la primera, no necesita lanzar, porque sabe que la asignación estará bien. Pero cuando asigna de una variable a otra cuyo rango es un subconjunto, necesita lanzar, porque la asignación puede no ser posible.

Imagine que tiene dos contenedores: una tina de plástico y una cesta de compras de alambre del mismo tamaño. Claramente, cualquier cosa que pueda guardar en la canasta de alambre, puede guardarla en la tina. Pero no todo lo que puede guardar en la bañera puede guardarse en la canasta. Una pila de manzanas, puedes. Pero un montón de pasas, no puedes, caen a través de los agujeros en la canasta. Por lo tanto, el rango de cosas que la bañera puede contener es mayor que el rango de cosas que la canasta puede contener, aunque ambas tienen el mismo tamaño.

En esa analogía, la fundición es como comprobar si lo que está moviendo encajará en el nuevo contenedor. No es necesario que verifique cuándo mueve las cosas de la canasta a la bañera, pero sí debe verificar cuándo se mueve de la bañera a la canasta, de lo contrario terminará con fruta en todo el piso.

En sus casos específicos, sabemos que cada ser humano es un mamífero, pero que no todos los mamíferos son humanos, por lo que el rango de una variable de tipo Mamífero es mayor que el de una variable de tipo Humano. También sabemos que el rango de un doble (aproximadamente 2^1024 - - (2^1024)) es mayor que el de un int (2^31-1 - -2^31). Por lo tanto, asignar de la primera a la última en cualquier caso requiere un elenco, pero de la segunda a la primera no.

6

Cuando utiliza tipos primitivos, debe emitir explícitamente cuando existe la posibilidad de que pierda información. Por ejemplo, long es de 64 bits y int es 32. Convertir un long en un int puede provocar la pérdida de datos (32 bits en este caso).

Cuando se trata de objetos, esto es relativo al polimorfismo. El compilador puede garantizar que cada Human es un Mammal. No hay problema aqui Pero no puede garantizar que cada Mammal sea Human. Debe convertir explícitamente para convertir el tipo de referencia.

Puede ver conversiones explícitas como una forma de decirle al compilador "Sé que no puede garantizar que la conversión de datos sea segura, pero sé lo que estoy haciendo".

+0

Si las reglas de Java se basaban en la pérdida de datos, la única conversión implícita de entero a punto flotante sería 'int-> double'. Podría pensar en buenas razones para prohibir conversiones con pérdidas, o para permitir 'double-> float'; Creo que las reglas actuales de Java tienen un aspecto sustancial del peor de los dos mundos, ya que algo como 'double d = 1234567890 -1f;' convertirá silenciosamente 1234567890 a 1234567936.0f inexacto (obteniendo un resultado de 1234567936.0) en lugar de a la precisión 1234567890.0 (que daría el 1234567889.0 aritméticamente correcto). – supercat

1
  1. En caso de la memoria primitivas entra en play.If que se va a almacenar el doble en int como en tu ejemplo, doble toma más memoria como comparar a integer.So no hay posibilidad de error del compilador tiro datos lose.So .Si te lanzas, entonces sabes lo que estás haciendo para que el compilador lo haga.
  2. En caso de objeto, no hay memoria allí. Solo polimorfismo entra en juego. Así que puede tomar un objeto de subclase en supertipo.

    Espero que lo obtengas.

Cuestiones relacionadas