El mecanismo de conversión de tipos en Java (type casting) permite al programador convertir explícita o implícitamente un valor de un tipo a otro. Históricamente, esta característica ha sido heredada de C y C++, pero en Java está limitada para aumentar la seguridad de tipos y prevenir errores ocultos relacionados con desbordamientos o pérdida de datos.
El problema radica en la posibilidad de que se produzca una ClassCastException al convertir tipos de referencia, así como en la pérdida de precisión al convertir tipos primitivos, por ejemplo, al pasar de double a int. Pueden ocurrir errores lógicos en el llamado "downcasting" (conversión a un tipo de hijo), si la instancia no pertenece a esa clase.
La solución consiste en una estricta separación:
Ejemplo de código para primitivos:
int i = 100; long l = i; // conversión implícita (int -> long) double d = l; // implícita (long -> double) int i2 = (int) d; // conversión explícita (pérdida de la parte decimal)
Ejemplo de código para tipos de referencia:
Object obj = "Hola"; // upcasting, implícitamente String s = (String) obj; // downcasting, explícitamente
Características clave:
¿Puede el compilador Java prevenir todas las conversiones de tipos erróneas?
Respuesta: No, el compilador solo detecta errores obvios en la etapa de compilación. Si la conversión es posible en la estructura de tipos (por ejemplo, Object -> String), pero la variable en realidad contiene un objeto de tipo incompatible, el error se manifestará solo en tiempo de ejecución con ClassCastException.
¿Hereda Integer de Long, y se puede escribir Integer i = (Integer) someLong?
Respuesta: No, Integer y Long son clases envolventes independientes, no se puede hacer downcasting entre ellas. Ambas heredan de Number, pero no entre sí. La conversión del tipo (Integer) (Object) 1L; causará ClassCastException.
¿Se realiza redondeo de la parte decimal al convertir float a int?
Respuesta: No, se descarta la parte decimal sin redondeo:
float f = 3.99f; int i = (int) f; // i == 3, no 4
Un desarrollador recibe una colección de Object, convierte cada elemento a su tipo, pero no verifica instanceof. El proyecto falla constantemente con ClassCastException al recibir datos incorrectos.
Pros:
Contras:
Todas las operaciones de downcasting se realizan dentro de if (obj instanceof TargetType) con un manejo explícito de errores. Se utilizan genéricos para colecciones.
Pros:
Contras: