Java
Variables, tipos de datos y operadores
Tipos primitivos, tipado estático, la palabra var, operadores y la constante final en Java.
De la variable nombre a los tipos de datos
En el segundo ejemplo de ¿Qué es Java? apareció esta línea:
String nombre = teclado.nextLine();Ahí nombre es una variable: un espacio con nombre donde el programa guarda un valor para usarlo más adelante. Lo que no se explicó en ese momento es la palabra String que va justo antes: en Java, toda variable declara su tipo por escrito en el momento en que se crea, y ese tipo no cambia después. Esta página cubre qué tipos existen, qué operaciones se pueden hacer con ellos, y qué pasa cuando ese tipo no se respeta.
Tipado estático
Java es de tipado estático: el tipo de cada variable queda fijado en el momento de declararla, y el compilador lo verifica antes de que el programa corra siquiera una vez. Si intentas guardar un valor que no encaja con el tipo declarado, el error aparece al compilar, no mientras el programa está corriendo.
int edad = 25;
edad = "veinticinco"; // no compilaEl compilador rechaza esa segunda línea con este mensaje:
error: incompatible types: String cannot be converted to intSi conoces algún lenguaje de tipado dinámico (Python, JavaScript), la diferencia es esta: ahí el propio valor “sabe” su tipo, y una misma variable puede apuntar primero a un número y después a un texto sin que nadie se queje. En Java la variable tiene un tipo fijo, elegido de antemano, y ese tipo no cambia en toda su vida.
Tipos primitivos
Java tiene ocho tipos primitivos: valores simples que no son objetos y que la JVM guarda directamente, sin la maquinaria de una clase. Los que vas a usar constantemente son estos cuatro, más long para números enteros que se quedan cortos en int:
| Tipo | Qué guarda | Ejemplo | Tamaño típico |
|---|---|---|---|
int | Números enteros | int edad = 25; | 32 bits |
double | Números con decimales | double precio = 19.99; | 64 bits |
boolean | Verdadero o falso | boolean activo = true; | 1 bit (conceptual) |
char | Un único carácter | char inicial = 'A'; | 16 bits |
long | Enteros muy grandes (más que int) | long poblacion = 8000000000L; | 64 bits |
De dónde vienen estos nombres, palabra por palabra: int es una abreviación de integer (“entero” en inglés matemático — un número sin parte decimal). double viene de “doble precisión”, una forma técnica de guardar números con decimales que ocupa el doble de espacio que otra más simple (float) a cambio de más exactitud — no hace falta entender el detalle técnico, solo que “usa double para decimales” es la regla práctica. char es abreviación de character (“carácter”: una sola letra, dígito o símbolo). boolean no viene del inglés común sino del apellido de George Boole, un matemático — un boolean es un valor que solo puede ser una de dos cosas, verdadero o falso, como el interruptor de la luz: prendido o apagado, sin punto intermedio.
Algunas aclaraciones puntuales:
charusa comillas simples ('A'), nunca comillas dobles — esas son paraString.- Un literal
longtermina enL(mayúscula o minúscula): sin esaL, Java lo trata comoint, y si el número es demasiado grande para caber en unint, el programa no compila. - El “tamaño típico” lo fija la especificación del lenguaje, no el sistema operativo ni el procesador donde corra.
Existen otros tres primitivos (byte, short, float) para casos puntuales de ahorro de memoria o precisión distinta a double. No hacen falta para empezar, así que quedan fuera de esta introducción.
Tipos primitivos vs. clases envoltorio
Cada tipo primitivo tiene una clase envoltorio (wrapper class) equivalente: int tiene Integer, double tiene Double, boolean tiene Boolean, y así con el resto. Un primitivo es un valor simple; su envoltorio es un objeto que guarda ese mismo valor pero con la maquinaria completa de una clase (métodos propios, la posibilidad de valer null, etc.).
Por ahora no necesitas usarlas a propósito, pero es común encontrártelas en código ajeno o en mensajes de error, así que vale la pena reconocerlas: si ves Integer donde esperabas int, es la versión “objeto” del mismo número. Java convierte entre una forma y la otra automáticamente en la mayoría de los casos (una técnica llamada autoboxing), pero ese es un detalle que no hace falta dominar todavía — solo que no te sorprenda verlo.
String no es un tipo primitivo
String no aparece en la tabla de arriba a propósito: es una clase, no un primitivo — igual que Scanner, no es parte del lenguaje en sí sino de la biblioteca estándar de Java. La diferencia con Scanner es que a String no hace falta importarla: se usa tanto que Java la deja disponible en todo programa sin ningún import.
String saludo = "Hola";La diferencia práctica más visible frente a los primitivos es que un String se escribe siempre entre comillas dobles, mientras que los números y boolean no llevan comillas.
Inferencia de tipo con var
Desde Java 10, se puede reemplazar el nombre del tipo por la palabra var en una variable local, y el compilador lo deduce a partir del valor que se le asigna:
var edad = 25; // el compilador deduce int
var nombre = "Ana"; // el compilador deduce Stringvar no convierte a Java en un lenguaje de tipado dinámico. El tipo se sigue fijando en tiempo de compilación, exactamente igual que si lo hubieras escrito a mano — la única diferencia es que no lo escribiste tú, lo dedujo el compilador a partir del valor inicial. Por eso var edad = 25; edad = "veinticinco"; sigue sin compilar: edad quedó fijada como int desde su declaración. Tampoco es lo mismo que Object: var no envuelve el valor en un tipo genérico, simplemente evita que tengas que escribir el nombre del tipo real.
var necesita un valor inicial en la misma línea donde se declara — si no, el compilador no tiene de dónde deducir el tipo — y solo se puede usar para variables locales (dentro de un método), no para atributos de una clase.
Operadores aritméticos, de comparación y lógicos
Con a = 7 y b = 2:
| Categoría | Operador | Qué hace | Ejemplo | Resultado |
|---|---|---|---|---|
| Aritmético | + - * | Suma, resta, multiplicación | a + b | 9 |
| Aritmético | / | División | a / b | 3 |
| Aritmético | % | Resto de la división | a % b | 1 |
| Comparación | == != | Igual / distinto | a == b | false |
| Comparación | < > <= >= | Comparación de orden | a > b | true |
| Lógico | && | Y lógico: ambas verdaderas | a > 0 && b > 0 | true |
| Lógico | || | O lógico: al menos una verdadera | a > 0 || b > 0 | true |
| Lógico | ! | Niega el valor | !(a > b) | false |
Los paréntesis agrupan una expresión y fuerzan el orden en que se evalúa, igual que en una expresión matemática: (a + b) * 2 no es lo mismo que a + b * 2.
7 / 2 da 3, no 3.5. Cuando los dos operandos de / son int, Java hace división entera: descarta la parte decimal en vez de redondear. Para obtener 3.5 hace falta que al menos uno de los dos operandos sea double: 7.0 / 2 o (double) 7 / 2. Esta es la misma trampa que existe en C y C++.
final: variables que no cambian
La palabra clave final convierte una variable en de asignación única: una vez que le das un valor, no se puede reasignar. Es el equivalente en Java de una constante.
final double IVA = 0.19;
IVA = 0.21; // no compilaEl compilador responde:
error: cannot assign a value to final variable IVAPor convención, las constantes final se escriben en mayúsculas con guiones bajos (IVA, MAX_INTENTOS), para distinguirlas a simple vista de una variable normal.
Ejemplo completo
public class Main {
public static void main(String[] args) {
final double IVA = 0.19;
double precioBase = 19.99;
int cantidad = 3;
double subtotal = precioBase * cantidad;
double total = subtotal + (subtotal * IVA);
boolean superaEnvioGratis = total >= 50.0;
System.out.println("Subtotal: " + subtotal);
System.out.println("Total con IVA: " + total);
System.out.println("¿Envío gratis? " + superaEnvioGratis);
}
}javac Main.java
java MainSubtotal: 59.97
Total con IVA: 71.3643
¿Envío gratis? truePon a prueba
¿Qué imprime este programa? Presta atención al tipo de cada operando en la división.
public class Main {
public static void main(String[] args) {
int a = 9;
int b = 4;
double resultado = a / b;
System.out.println(resultado);
}
}Imprime 2.0, no 2.25. La división a / b ocurre antes de asignarse a resultado: como a y b son los dos int, Java hace división entera y obtiene 2 — recién ahí ese 2 se convierte a double para guardarse. Que la variable de destino sea double no cambia cómo se calculó la división. Para obtener 2.25 hace falta forzar el tipo antes de dividir, por ejemplo con (double) a / b.
Ordena las líneas para declarar dos constantes final y calcular el área de un rectángulo.
- System.out.println("Área: " + area);
- }
- double area = BASE * ALTURA;
- }
- final double ALTURA = 2.0;
- public static void main(String[] args) {
- final double BASE = 4.5;
- public class Main {
Siguiente paso
Con variables y operadores ya puedes calcular cosas, pero el programa sigue ejecutándose siempre de arriba a abajo, sin importar lo que valgan esas variables. Para que decida y repita trabajo, sigue con Control de flujo: if, for, while y switch.