Sistema de tipos
Primitivos, referencias, autoboxing y null
Tipos primitivos
Los ocho primitivos son los únicos tipos que no son objetos en Java. Se almacenan directamente en la pila (o en el heap dentro de un objeto), sin overhead de cabecera de objeto. Son siempre de tamaño fijo, independientemente de la plataforma.
// Ocho tipos primitivos en Java
byte b = 127; // 8 bits, -128..127
short s = 32767; // 16 bits
int i = 2_147_483_647;// 32 bits (literal con guiones bajos para legibilidad)
long l = 9_000_000_000L; // 64 bits, sufijo L obligatorio
float f = 3.14f; // 32 bits IEEE 754, sufijo f
double d = 3.14159265; // 64 bits IEEE 754
boolean flag = true;
char c = 'A'; // 16 bits, Unicode UTF-16 Tipos referencia y null
Todo lo demás es un tipo referencia: clases, interfaces, arrays. Una variable de tipo referencia almacena la
dirección del objeto en el heap, no el objeto en sí. null indica ausencia de referencia — acceder
a cualquier método o campo de una referencia nula lanza
NullPointerException.
// Los tipos referencia almacenan una dirección, no el valor
String s1 = "hola";
String s2 = s1; // s2 apunta al mismo objeto
// null: ausencia de referencia
String s3 = null; // s3 no apunta a ningún objeto
s3.length(); // NullPointerException
// Comparación: == compara referencias, no contenido
String a = new String("hola");
String b = new String("hola");
a == b; // false: objetos distintos en memoria
a.equals(b); // true: mismo contenido Autoboxing y unboxing
Java convierte automáticamente entre primitivos y sus tipos envolventes (wrappers). Esto permite usar
primitivos donde se espera un Object o en colecciones genéricas. El compilador inserta las llamadas
a valueOf() y intValue()
silenciosamente.
// Autoboxing: primitivo → objeto envolvente (wrapper)
int primitivo = 42;
Integer objeto = primitivo; // autoboxing automático
Integer otro = Integer.valueOf(42); // equivalente explícito
// Unboxing: objeto → primitivo
int desempaquetado = objeto; // unboxing automático
// Wrappers disponibles:
// int → Integer, long → Long, double → Double, boolean → Boolean
// char → Character, byte → Byte, short → Short, float → Float
// TRAMPA: unboxing de null lanza NullPointerException
Integer nulo = null;
int valor = nulo; // NullPointerException Cache de wrappers y rendimiento
// Cache de Integer: -128..127 reutilizan la misma instancia
Integer a = 100;
Integer b = 100;
a == b; // true — misma instancia cacheada
Integer c = 200;
Integer d = 200;
c == d; // false — instancias distintas (fuera del rango de cache)
// Moraleja: nunca comparar wrappers con ==, usar equals()
c.equals(d); // true — correcto
// Coste de autoboxing en bucles intensivos
long suma = 0;
// LENTO: crea un Long en cada iteración del bucle
for (Long i = 0L; i < 1_000_000; i++) suma += i; // evitar
// RÁPIDO: todo en primitivos
long suma2 = 0;
for (long i = 0; i < 1_000_000; i++) suma2 += i;