specific - Variables de lanzamiento en Java
funcion cast en java (4)
Me pregunto si alguien podría decirme cómo funciona el casting. Entiendo cuándo debo hacerlo, pero realmente no cómo funciona. En los tipos de datos primitivos lo entiendo parcialmente, pero cuando se trata de lanzar objetos no entiendo cómo funciona.
¿Cómo se puede convertir un objeto con el tipo Objeto de repente, digamos, MyType
(solo un ejemplo) y luego obtener todos los métodos?
Casting en Java no es mágico, es usted quien le dice al compilador que un Objeto de tipo A es en realidad de tipo B más específico, y por lo tanto tiene acceso a todos los métodos en B que de otro modo no habría tenido. No estás realizando ningún tipo de magia o conversión cuando realizas un casting, básicamente le estás diciendo al compilador "créeme, sé lo que estoy haciendo y puedo garantizarte que este Object en esta línea es en realidad un <Insert cast escribe aquí>. " Por ejemplo:
Object o = "str";
String str = (String)o;
Lo anterior está bien, no es magia y todo está bien. El objeto que se almacena en o es en realidad una cadena y, por lo tanto, podemos convertirlo a una cadena sin ningún problema.
Hay dos formas en que esto podría salir mal. En primer lugar, si estás eligiendo entre dos tipos en jerarquías de herencia completamente diferentes, entonces el compilador sabrá que estás siendo tonto y te detendrá:
String o = "str";
Integer str = (Integer)o; //Compilation fails here
En segundo lugar, si están en la misma jerarquía pero aún tienen una conversión inválida, se lanzará una ClassCastException
en el tiempo de ejecución:
Number o = new Integer(5);
Double n = (Double)o; //ClassCastException thrown here
Esto esencialmente significa que has violado la confianza del compilador. Usted le ha dicho que puede garantizar que el objeto es de un tipo particular, y no lo es.
¿Por qué necesitas casting? Bueno, para comenzar solo lo necesitas cuando pasas de un tipo más general a un tipo más específico. Por ejemplo, Integer
hereda de Number
, así que si quieres almacenar un Integer
como un Number
entonces está bien (ya que todos los Enteros son Números). Sin embargo, si quieres ir al revés necesitas un yeso, no todos los Números son Enteros (así como Integer tenemos Double
, Float
, Byte
, Long
, etc.) E incluso si solo hay una subclase en su proyecto o el JDK, alguien podría crear fácilmente otra y distribuirla, por lo que no tiene garantía, incluso si ¡crees que es una elección única y obvia!
En cuanto al uso para el casting, aún se ve la necesidad en algunas bibliotecas. Pre Java-5 se usó mucho en colecciones y varias otras clases, ya que todas las colecciones trabajaban en la adición de objetos y luego arrojaban el resultado de que recuperaste la colección. Sin embargo, con el advenimiento de los genéricos, gran parte del uso del casting se ha ido: ha sido reemplazado por genéricos que ofrecen una alternativa mucho más segura, sin el potencial de ClassCastExceptions (de hecho, si utilizas los genéricos limpiamente y compila sin advertencias, usted tiene una garantía de que nunca obtendrá una ClassCastException).
En realidad, el casting no siempre funciona. Si el objeto no es una instanceof
la clase a la que lo está enviando, obtendrá una ClassCastException
en tiempo de ejecución.
Lanzar una referencia solo funcionará si es una instanceof
ese tipo. No puedes lanzar referencias aleatorias. Además, necesita leer más sobre Casting Objects
.
p.ej
String string = "String";
Object object = string; // Perfectly fine since String is an Object
String newString = (String)object; // This only works because the `reference` object is pointing to a valid String object.
Supongamos que quiere lanzar un String a un archivo (sí, no tiene sentido), no puede convertirlo directamente porque la clase File no es un elemento secundario y no es un elemento primario de la clase String (y el compilador se queja). Pero podría convertir su Cadena en Objeto, porque una Cadena es un Objeto (El Objeto es el padre). Entonces podrías convertir este objeto a un Archivo, porque un Archivo es un Objeto. De modo que todas sus operaciones son ''legales'' desde un punto de vista de tipeo en tiempo de compilación, ¡pero eso no significa que funcionará en tiempo de ejecución!
File f = (File)(Object) "Stupid cast";
El compilador permitirá esto incluso si no tiene sentido, pero se bloqueará en tiempo de ejecución con esta excepción:
Exception in thread "main" java.lang.ClassCastException:
java.lang.String cannot be cast to java.io.File