Conversiones de tipo
Widening, narrowing y casting explícito
Widening (ampliación implícita)
Java convierte automáticamente de tipos más pequeños a más grandes cuando no hay pérdida de información. El
compilador lo inserta sin necesidad de cast. La excepción es
long → float: aunque el float es más "grande", puede perder dígitos significativos por
diferencia de representación.
// Widening (ampliación): conversión automática sin pérdida de información
// El compilador la hace implícitamente
byte b = 100;
short s = b; // byte → short: automático
int i = s; // short → int: automático
long l = i; // int → long: automático
float f = l; // long → float: automático (puede perder precisión en valores grandes)
double d = f; // float → double: automático
// Jerarquía de widening: byte → short → int → long → float → double
// char → int también es widening (char es un entero sin signo de 16 bits)
char c = 'A';
int ascii = c; // 65 Narrowing (reducción explícita)
Convertir a un tipo de menor capacidad requiere un cast explícito. El programador asume la responsabilidad
de que el valor cabe — si no cabe, se trunca o desborda silenciosamente. Para referencias, el cast puede
lanzar ClassCastException si el tipo real no es compatible.
// Narrowing (reducción): requiere cast explícito — puede perder información
double d = 9.99;
int i = (int) d; // 9: trunca la parte decimal, no redondea
long l = 300L;
byte b = (byte) l; // posible desbordamiento: 300 % 256 = 44
// Cast entre tipos referencia: funciona si el tipo real es compatible
Object obj = "hola"; // tipo real: String
String s = (String) obj; // OK: el objeto realmente es un String
Object otro = Integer.valueOf(42);
String s2 = (String) otro; // ClassCastException en tiempo de ejecución
// instanceof: verificar antes de hacer cast
if (obj instanceof String) {
String str = (String) obj; // seguro
System.out.println(str.toUpperCase());
} Conversiones con String
Las conversiones entre tipos numéricos y String se hacen con métodos estáticos de las clases envolventes.
parseInt, parseDouble, etc. lanzan
NumberFormatException si la cadena no tiene el formato esperado.
// Conversiones a y desde String
// Primitivo → String
int n = 42;
String s1 = String.valueOf(n); // "42"
String s2 = Integer.toString(n); // "42"
String s3 = "" + n; // "42" (por concatenación — menos eficiente)
// String → primitivo
String texto = "123";
int i = Integer.parseInt(texto); // 123
double d = Double.parseDouble("3.14"); // 3.14
boolean b = Boolean.parseBoolean("true"); // true
// NumberFormatException si el String no es un número válido
try {
int x = Integer.parseInt("abc"); // lanza NumberFormatException
} catch (NumberFormatException e) {
System.err.println("No es un número");
} Promoción aritmética
En operaciones aritméticas, Java promueve los operandos al tipo más amplio. El caso más sorprendente: byte + byte produce un int. Y la división entre enteros trunca — para obtener decimales hay que forzar al
menos uno de los operandos a double.
// Promoción aritmética: operaciones entre tipos distintos
byte b1 = 10, b2 = 20;
// byte + byte → int (los operandos se promueven a int)
// byte resultado = b1 + b2; // Error de compilación
int resultado = b1 + b2; // correcto
// int / int → int (división entera, pierde decimales)
int a = 7, b = 2;
int cociente = a / b; // 3
double exacto = (double) a / b; // 3.5: cast necesario en el numerador
// Concatenación: si un operando es String, el otro se convierte a String
String s = "Resultado: " + 42; // "Resultado: 42"
String t = 1 + 2 + " total"; // "3 total" (1+2 se suman primero, luego se concatenan)
String u = "total: " + 1 + 2; // "total: 12" (concatenación de izquierda a derecha)