Me pregunto si alguien podría decirme cómo funciona el casting. Entiendo cuándo debería hacerlo, pero no realmente cómo funciona. En los tipos de datos primitivos, 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?
Respuestas:
Transmitir en Java no es mágico, le dice al compilador que un Objeto de tipo A es en realidad de tipo B más específico y, por lo tanto, obtiene acceso a todos los métodos en B que de otra manera no habría tenido. No está realizando ningún tipo de magia o conversión al realizar un casting, esencialmente le está diciendo al compilador "confía en mí, sé lo que estoy haciendo y puedo garantizarle que este Objeto en esta línea es en realidad un <Insertar escriba aquí>. " Por ejemplo:
Object o = "str"; String str = (String)o;
Lo anterior está bien, no es mágico y todo está bien. El objeto que se almacena en o es en realidad una cadena y, por lo tanto, podemos convertir a una cadena sin ningún problema.
Hay dos formas en que esto podría salir mal. En primer lugar, si está lanzando entre dos tipos en jerarquías de herencia completamente diferentes, el compilador sabrá que está siendo tonto y lo detendrá:
String o = "str"; Integer str = (Integer)o; //Compilation fails here
En segundo lugar, si están en la misma jerarquía pero siguen siendo un elenco no válido, se
ClassCastException
lanzará un en tiempo de ejecución:Number o = new Integer(5); Double n = (Double)o; //ClassCastException thrown here
Esto esencialmente significa que ha violado la confianza del compilador. Le ha dicho que puede garantizar que el objeto es de un tipo en particular, y no lo es.
¿Por qué necesitas un casting? Bueno, para empezar solo lo necesitas cuando pasas de un tipo más general a un tipo más específico. Por ejemplo,
Integer
hereda deNumber
, por lo que si desea almacenar unInteger
como a,Number
entonces está bien (ya que todos los enteros son números) .Sin embargo, si desea ir al revés, necesita un reparto; no todos los números son enteros (también como entero que tenemosDouble
,Float
,Byte
,Long
, etc.) e incluso si sólo hay una subclase en su proyecto o el JDK, alguien podría fácilmente crear otro y distribuir eso, así que usted no tiene ninguna garantía, incluso si usted piensa que es una sola opción, obvia !Con respecto al uso para la transmisión, todavía ve la necesidad de hacerlo en algunas bibliotecas. Antes de Java-5 se usaba mucho en colecciones y varias otras clases, ya que todas las colecciones trabajaban para agregar objetos y luego emitir el resultado que obtuviste de la colección. Sin embargo, con la llegada de los genéricos, gran parte del uso del casting ha desaparecido: ha sido reemplazado por genéricos que brindan una alternativa mucho más segura, sin el potencial de ClassCastExceptions (de hecho, si usa genéricos de manera limpia y se compila sin advertencias, tiene la garantía de que nunca obtendrá una ClassCastException).
fuente
Double.valueOf(gpsLastLoc.getLatitude()).getClass().getSimpleName()
. En cualquier caso, nunca debería necesitar obtener la clase de una primitiva dinámicamente, ya que sigetLatitude()
devuelve una primitiva doble, siempre sabrá que se promoverá a unDouble
objeto.En realidad, el casting no siempre funciona. Si el objeto no es una
instanceof
clase a la que lo estás enviando, obtendrás unClassCastException
tiempo de ejecución.fuente
Suponga que desea convertir a
String
a aFile
(sí, no tiene ningún sentido), no puede convertirlo directamente porque laFile
clase no es un hijo ni un padre de laString
clase (y el compilador se queja).Pero podrías lanzar tu
String
toObject
, porque aString
es unObject
(Object
es padre). Entonces podría convertir este objeto a aFile
, porque un archivo es unObject
.Así que todas sus operaciones son 'legales' desde el punto de vista de la escritura 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
fuente
Enviar una referencia solo funcionará si es de
instanceof
ese tipo. No puedes emitir referencias al azar. Además, necesita leer más sobreCasting 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.
fuente
La forma correcta es esta:
El método
cast()
es una alternativa mucho más segura a la conversión en tiempo de compilación.fuente