W3docs

Tipos de datos en Java

Explora los tipos de datos primitivos de Java (byte, short, int, long, float, double, char, boolean) y los tipos de referencia.

Java es tipado estáticamente — cada variable tiene un tipo conocido en tiempo de compilación. Los tipos se dividen en dos familias: primitivos (valores básicos integrados en el lenguaje) y tipos de referencia (objetos, arrays, cualquier cosa creada con new). Este capítulo recorre ambos.

Los ocho tipos primitivos

Los primitivos son los únicos valores en Java que no son objetos. Almacenan su valor directamente en el espacio de almacenamiento de la variable. Java define exactamente ocho:

TipoTamañoRangoPor defectoLiteral de ejemplo
byte8 bits-128 a 1270byte b = 100;
short16 bits-32,768 a 32,7670short s = 30000;
int32 bits-2³¹ a 2³¹-1 (≈ ±2.1 mil millones)0int i = 1_000_000;
long64 bits-2⁶³ a 2⁶³-10Llong l = 9_000L;
float32 bitsPrecisión simple IEEE 7540.0ffloat f = 3.14f;
double64 bitsPrecisión doble IEEE 7540.0double d = 3.14;
char16 bitsUnidad de código Unicode (U+0000 a U+FFFF)\0char c = 'A';
booleanDefinido por JVMtrue o falsefalseboolean b = true;

Algunas cosas que vale la pena memorizar:

  • int es el tipo entero por defecto. La mayoría de los contadores e índices son int. Usa long solo cuando realmente necesites números superiores a ~2 mil millones.
  • double es el tipo de punto flotante por defecto. El valor 3.14 simple es un double; 3.14f es un float. Usa double salvo que la presión de memoria obligue a usar float.
  • Los guiones bajos en literales numéricos mejoran la legibilidad: 1_000_000 es lo mismo que 1000000.
  • Los valores por defecto se aplican solo a los campos, no a las variables locales. Una variable local no tiene valor por defecto — debes inicializarla antes de leerla.

Tipos de referencia

Todo lo demás — String, arrays, tus propias clases, clases de biblioteca — es un tipo de referencia. Una variable de tipo de referencia no contiene el objeto en sí; contiene una referencia (esencialmente un puntero) al objeto en el heap:

String name = "Ada";
int[] scores = new int[10];
LocalDate today = LocalDate.now();

El valor por defecto de cualquier variable de referencia es null — un valor especial que significa "ningún objeto."

String s = null;
System.out.println(s.length());  // throws NullPointerException at runtime

null es la fuente de uno de los errores en tiempo de ejecución más comunes en Java. El capítulo Java Exceptions explica cómo manejar la NullPointerException que esto genera.

Clases envolventes

Cada primitivo tiene una clase envolvente correspondiente — un objeto real que encapsula el valor primitivo:

PrimitivoEnvolvente
byteByte
shortShort
intInteger
longLong
floatFloat
doubleDouble
charCharacter
booleanBoolean

Necesitas las envolventes cuando quieres poner primitivos en colecciones (que solo contienen objetos):

List<Integer> scores = new ArrayList<>();
scores.add(42);   // autoboxed from int → Integer
int first = scores.get(0);  // unboxed from Integer → int

Java convierte automáticamente entre primitivos y envolventes — llamado autoboxing y unboxing — así que la mayoría del tiempo no lo notas.

Una nota sobre String

String es un tipo de referencia, no un primitivo. Es lo suficientemente especial como para que el lenguaje le dé una sintaxis literal ("texto") y el operador +. Los strings son inmutables — una vez creados, su contenido nunca cambia. Cada "modificación" devuelve un nuevo string. El capítulo Java Strings profundiza en esto.

Elegir un tipo

Un árbol de decisión breve para el Java cotidiano:

  • Contar cosas o índices de arraysint
  • Conteos grandes (tamaños de archivo, marcas de tiempo en milisegundos)long
  • DineroBigDecimal (no double — el redondeo de punto flotante te causará problemas)
  • Un solo carácterchar
  • Sí/noboolean
  • TextoString
  • Una fecha u hora → tipos en java.time (LocalDate, Instant, Duration)

Resiste la tentación de "ahorrar memoria" usando byte o short para enteros ordinarios. Las JVM están optimizadas para operaciones con int; short en realidad no usa menos memoria en la mayoría de los casos.

Errores comunes

Algunos comportamientos de tipos sorprenden regularmente a los principiantes. Conocerlos de antemano ahorra horas de depuración.

El desbordamiento de enteros ocurre silenciosamente

La aritmética entera en Java nunca lanza una excepción por desbordamiento — da la vuelta. Sumar 1 al int más grande produce el int más pequeño:

int max = Integer.MAX_VALUE;   // 2147483647
System.out.println(max + 1);   // -2147483648

Si un valor puede superar ~2.1 mil millones, usa long. Para conteos que podrían desbordar incluso long, recurre a BigInteger.

El punto flotante no es exacto

float y double siguen el estándar IEEE 754, que no puede representar la mayoría de las fracciones decimales con exactitud. El ejemplo clásico:

System.out.println(0.1 + 0.2);   // 0.30000000000000004

Por eso nunca debes usar double para dinero. Usa BigDecimal (construido desde un String, por ejemplo new BigDecimal("0.1")) cuando los valores decimales exactos importen.

char es un número

Un char es un entero sin signo de 16 bits que contiene una unidad de código Unicode, por lo que participa en aritmética:

char a = 'A';
System.out.println((int) a);   // 65
System.out.println((char) (a + 1));  // B

Compara envolventes con .equals(), no con ==

== en objetos envolventes compara referencias, no valores. Debido a una caché de autoboxing para valores pequeños de Integer (-128 a 127), == parece funcionar para números pequeños y luego falla para números grandes:

Integer a = 127, b = 127;
System.out.println(a == b);   // true  (cached)
Integer c = 128, d = 128;
System.out.println(c == d);   // false (different objects)
System.out.println(c.equals(d));  // true  (compares values)

Usa siempre .equals() para comparar valores envolventes. Consulta Java Type Casting para conocer las reglas de conversión entre estos tipos.

Una demostración en funcionamiento

java— editable, runs on the server

Qué sigue

Java Type Casting muestra cómo convertir entre tipos numéricos y entre tipos de referencia relacionados.

Práctica

Práctica
¿Cuáles afirmaciones sobre los tipos de datos de Java son correctas?
¿Cuáles afirmaciones sobre los tipos de datos de Java son correctas?
Was this page helpful?