Variables y tipos de datos en Java
En esta lección
- Tipado estático: cada variable tiene un tipo
- Los 8 tipos primitivos
- String: texto
- Declarar e inicializar
- Literales: cómo escribir los valores
- var: que Java deduzca el tipo
- Constantes con final
- Conversiones entre tipos
- Dos trampas: desbordamiento y división entera
- Primitivos frente a referencias
- Errores frecuentes
- 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:
| Tipo | Tamaño | Rango | Uso típico |
|---|---|---|---|
byte | 8 bits | -128 a 127 | Datos binarios, ficheros |
short | 16 bits | -32 768 a 32 767 | Casi no se usa |
int | 32 bits | -2 147 483 648 a 2 147 483 647 | Enteros en general |
long | 64 bits | unos ±9,2 trillones (9,2 × 10¹⁸) | Enteros enormes, milisegundos |
float | 32 bits | unos 7 dígitos de precisión | Gráficos, poca memoria |
double | 64 bits | unos 15-16 dígitos de precisión | Decimales en general |
char | 16 bits | un carácter Unicode (0 a 65 535) | Una letra, un símbolo |
boolean | — | true o false | Condiciones |
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
Lde loslong: un número entero escrito tal cual es unint. Si supera su rango, no compila aunque la variable sealong:long x = 8100000000;da el error integer number too large. Usa laLmayúscula (la minúscula se confunde con un 1). - La
fde losfloat: un decimal escrito tal cual es undouble.float peso = 72.5;no compila porque se perdería precisión. - El guion bajo
_: puedes separar las cifras para leerlas mejor.1_000_000es exactamente lo mismo que1000000.
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
varcuando 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
| Primitivo | Referencia | |
|---|---|---|
| Ejemplos | int, double, boolean, char | String, arrays, objetos |
| Qué guarda | El valor | La dirección del objeto |
| Empieza por | Minúscula | Mayúscula (clases) |
Puede ser null | No | Sí |
Comparar con == | Compara valores | Compara 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
Lo laf:long x = 5000000000;yfloat 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 eschar, el segundoString. - Desbordar sin darte cuenta: en cálculos grandes, usa
longdesde el principio de la operación.
Resumen
- Java tiene 8 tipos primitivos; los habituales son
int,double,booleanychar. Stringes una clase: guarda texto entre comillas dobles.- Los literales tienen sufijos (
L,f) y admiten_para separar cifras. vardeduce el tipo en variables locales; el tipo sigue siendo fijo.finalcrea 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
¿Te ha quedado claro? Márcala y verás tu progreso en el explorador.