Saltar al contenido
variables.java · devschool

Variables y tipos de datos en Java

Lección 2 de 26 · 10 min de lectura · Actualizado el

En esta lección
  1. Tipado estático: cada variable tiene un tipo
  2. Los 8 tipos primitivos
  3. String: texto
  4. Declarar e inicializar
  5. Literales: cómo escribir los valores
  6. var: que Java deduzca el tipo
  7. Constantes con final
  8. Conversiones entre tipos
  9. Dos trampas: desbordamiento y división entera
  10. Primitivos frente a referencias
  11. Errores frecuentes
  12. Resumen

Una variable es un espacio con nombre donde el programa guarda un dato: la edad de un usuario, el precio de un producto o si un pedido está pagado. En esta lección vas a ver qué tipos de datos tiene Java, cómo se declaran las variables, cómo se convierten unos tipos en otros y qué errores silenciosos debes vigilar, como el desbordamiento o la división entera.

Tipado estático: cada variable tiene un tipo

En Java cada variable tiene un tipo fijo que se escribe al declararla. Si una variable es un número, no puede guardar un texto más adelante. A esto se le llama tipado estático, y su gran ventaja es que muchos errores se detectan al compilar, antes de ejecutar nada.

int edad = 25;
String nombre = "Ana";

La forma es siempre la misma: tipo, nombre, = y valor, terminado en punto y coma.

int edad = 25;
edad = "veinticinco"; // error de compilación: incompatible types

Los 8 tipos primitivos

Los tipos primitivos son los tipos básicos del lenguaje. Se escriben en minúscula y guardan directamente el valor. Java tiene exactamente ocho:

TipoTamañoRangoUso típico
byte8 bits-128 a 127Datos binarios, ficheros
short16 bits-32 768 a 32 767Casi no se usa
int32 bits-2 147 483 648 a 2 147 483 647Enteros en general
long64 bitsunos ±9,2 trillones (9,2 × 10¹⁸)Enteros enormes, milisegundos
float32 bitsunos 7 dígitos de precisiónGráficos, poca memoria
double64 bitsunos 15-16 dígitos de precisiónDecimales en general
char16 bitsun carácter Unicode (0 a 65 535)Una letra, un símbolo
boolean—true o falseCondiciones

En la práctica, el 90 % del tiempo usarás int, double, boolean y char. Los demás existen para casos concretos: long cuando int se queda corto y byte cuando trabajas con datos binarios.

Puedes consultar los límites desde el propio código:

public class Rangos {
    public static void main(String[] args) {
        System.out.println(Integer.MAX_VALUE); // 2147483647
        System.out.println(Integer.MIN_VALUE); // -2147483648
        System.out.println(Long.MAX_VALUE);    // 9223372036854775807
        System.out.println(Byte.MAX_VALUE);    // 127
    }
}

String: texto

El texto no es un tipo primitivo, sino una clase. Por eso String empieza por mayúscula. Los textos van entre comillas dobles:

String saludo = "Hola";
String nombre = "Luis";
String mensaje = saludo + ", " + nombre;

System.out.println(mensaje);               // Hola, Luis
System.out.println(mensaje.length());      // 10
System.out.println(mensaje.toUpperCase()); // HOLA, LUIS

Recuerda: 'A' (comillas simples) es un char; "A" (comillas dobles) es un String. Todos los métodos de texto los verás en String y StringBuilder.

Declarar e inicializar

Puedes declarar la variable y darle valor en la misma línea, o hacerlo en dos pasos:

int puntos;          // declarar
puntos = 10;         // inicializar (primera asignación)
puntos = puntos + 5; // reasignar
System.out.println(puntos); // 15

También puedes declarar varias del mismo tipo a la vez, aunque es más legible una por línea:

int ancho = 4, alto = 3;
System.out.println(ancho * alto); // 12

Java no deja usar una variable local sin valor. Este código no compila:

int total;
System.out.println(total); // error: variable total might not have been initialized

Es una protección: en otros lenguajes obtendrías un valor basura o undefined.

Literales: cómo escribir los valores

Un literal es un valor escrito directamente en el código. Cada tipo tiene su forma:

public class Literales {
    public static void main(String[] args) {
        int alumnos = 30;
        long poblacion = 8_100_000_000L; // L final: es un long
        double precio = 19.99;           // decimal: double por defecto
        float peso = 72.5f;              // f final: es un float
        char letra = 'B';
        char salto = '\n';               // carácter especial: salto de línea
        boolean pagado = true;
        int hexadecimal = 0xFF;          // 255 en base 16
        int binario = 0b1010;            // 10 en base 2

        System.out.println(poblacion);   // 8100000000
        System.out.println(peso);        // 72.5
        System.out.println(hexadecimal); // 255
        System.out.println(binario);     // 10
    }
}

Fíjate en tres detalles:

  • La L de los long: un número entero escrito tal cual es un int. Si supera su rango, no compila aunque la variable sea long: long x = 8100000000; da el error integer number too large. Usa la L mayúscula (la minúscula se confunde con un 1).
  • La f de los float: un decimal escrito tal cual es un double. float peso = 72.5; no compila porque se perdería precisión.
  • El guion bajo _: puedes separar las cifras para leerlas mejor. 1_000_000 es exactamente lo mismo que 1000000.

Los char admiten secuencias de escape: '\n' (salto de línea), '\t' (tabulador), '\'' (comilla simple) y '\\' (barra invertida).

var: que Java deduzca el tipo

Desde Java 10 puedes usar var en variables locales cuando el tipo es obvio por el valor:

var ciudad = "Santander"; // String
var total = 0;            // int
var media = 7.5;          // double

El tipo sigue siendo fijo: después no puedes guardar un texto en total. var solo ahorra escribir; no convierte Java en un lenguaje dinámico.

Limitaciones: var necesita un valor inicial (var x; no compila), no vale para atributos ni parámetros y no admite null como valor inicial.

Consejo: usa var cuando el tipo se vea a simple vista en la misma línea. Si el lector tiene que adivinarlo, escribe el tipo.

Constantes con final

Una variable final solo se puede asignar una vez. Por convenio, las constantes se escriben en MAYÚSCULAS con guiones bajos:

final double IVA = 0.21;
final int MAX_ALUMNOS = 30;
IVA = 0.10; // error: cannot assign a value to final variable IVA

¿Por qué usarlas? Porque el nombre IVA explica mucho más que un 0.21 suelto en mitad de una fórmula, y si el valor cambia solo lo tocas en un sitio. Las constantes de clase (static final) las verás en encapsulación.

Conversiones entre tipos

Conversión implícita (ensanchamiento)

De un tipo “pequeño” a uno “grande” Java convierte solo, porque no se pierde nada:

byte → short → int → long → float → double
         char ↗
int entero = 7;
long largo = entero;     // sin problema
double decimal = entero; // 7.0
System.out.println(decimal); // 7.0

Casting (estrechamiento)

Al revés hay que pedirlo a mano, poniendo el tipo entre paréntesis. Es tu forma de decirle a Java “sé que puedo perder información”:

double nota = 7.8;
int notaEntera = (int) nota;
System.out.println(notaEntera); // 7

double negativo = -3.9;
System.out.println((int) negativo); // -3

El casting a int corta los decimales, no redondea: 7.8 pasa a 7 y -3.9 pasa a -3. Para redondear usa Math.round, que verás en Math y clases envoltorio.

Los char son números por dentro (su código Unicode), así que también se pueden convertir:

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

De texto a número y al revés

Un String no se convierte con casting. Se usan métodos:

int edad = Integer.parseInt("25");
double precio = Double.parseDouble("19.99");
String texto = String.valueOf(42);
System.out.println(edad + 1);  // 26
System.out.println(texto + 1); // 421

Dos trampas: desbordamiento y división entera

Desbordamiento

Si un cálculo supera el máximo de su tipo, Java no avisa: el valor “da la vuelta” y aparece por el extremo contrario.

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

int segundosEnUnAnio = 365 * 24 * 60 * 60;
long milisMal = segundosEnUnAnio * 1000;  // se calcula en int y desborda
long milisBien = segundosEnUnAnio * 1000L; // se calcula en long
System.out.println(milisMal);  // 1471228928
System.out.println(milisBien); // 31536000000

En milisMal la variable es long, pero la multiplicación se hace entre dos int antes de guardarse, y ahí se desborda. Con 1000L la operación entera pasa a long.

División entera

Al dividir dos enteros, el resultado es entero y se descartan los decimales:

int suma = 25;
int cantidad = 4;
double mediaMal = suma / cantidad;          // se divide en int: 6
double mediaBien = (double) suma / cantidad;
System.out.println(mediaMal);  // 6.0
System.out.println(mediaBien); // 6.25

Lo verás con más detalle en operadores.

Primitivos frente a referencias

Hay una diferencia de fondo entre int y String:

  • Una variable primitiva guarda el valor directamente.
  • Una variable de referencia (String, arrays, cualquier objeto) guarda la dirección donde está el objeto en memoria.

Por eso al copiar un primitivo obtienes dos valores independientes:

int a = 5;
int b = a;
b = 10;
System.out.println(a); // 5

Con objetos, copiar la variable copia la dirección, y las dos apuntan al mismo objeto:

int[] original = {1, 2, 3};
int[] copia = original;
copia[0] = 99;
System.out.println(original[0]); // 99
PrimitivoReferencia
Ejemplosint, double, boolean, charString, arrays, objetos
Qué guardaEl valorLa dirección del objeto
Empieza porMinúsculaMayúscula (clases)
Puede ser nullNoSí
Comparar con ==Compara valoresCompara direcciones

Esto explica por qué los String se comparan con equals y no con ==. Lo retomarás en arrays y en clases y objetos.

Errores frecuentes

  • Olvidar la L o la f: long x = 5000000000; y float f = 1.5; no compilan.
  • Usar una variable sin inicializar: el compilador lo detecta y se niega.
  • Creer que (int) redondea: corta los decimales.
  • Confundir 'A' y "A": el primero es char, el segundo String.
  • Desbordar sin darte cuenta: en cálculos grandes, usa long desde el principio de la operación.

Resumen

  • Java tiene 8 tipos primitivos; los habituales son int, double, boolean y char.
  • String es una clase: guarda texto entre comillas dobles.
  • Los literales tienen sufijos (L, f) y admiten _ para separar cifras.
  • var deduce el tipo en variables locales; el tipo sigue siendo fijo.
  • final crea constantes, que se escriben en MAYÚSCULAS.
  • De pequeño a grande la conversión es automática; al revés necesitas casting, que corta decimales.
  • Vigila el desbordamiento y la división entera.
  • Los primitivos guardan valores; las referencias guardan direcciones de objetos.

En la siguiente lección aprenderás a operar con todos estos datos: operadores en Java.

Pon a prueba lo que has aprendido

[Java] ¿Qué tipo usarías para guardar un texto?

[Java] ¿Qué imprime este código?
double nota = 8.9;
int entera = (int) nota;
System.out.println(entera);

[Java] ¿Cuál de estas líneas NO compila?

¿Te ha quedado claro? Márcala y verás tu progreso en el explorador.