Todo programa informático, en su nivel más fundamental, consiste en procesar información: recibir datos del exterior, guardarlos temporalmente en la memoria, transformarlos mediante operaciones lógicas o matemáticas y devolver un resultado.
En este tema estudiaremos las herramientas esenciales que ofrece Java para realizar este ciclo. Aprenderemos cómo clasifica el lenguaje la información (tipado), cómo guardar datos en memoria (variables y constantes), los operadores para trabajar con ellos y los mecanismos para comunicarnos con el usuario a través de la consola.
Los lenguajes de programación se clasifican según cómo gestionan los tipos de sus datos:
Java es un lenguaje de tipado estático y fuertemente tipado (aunque realiza pequeñas conversiones implícitas seguras, como concatenar números a cadenas de texto).
public class Tipado {
static void main() {
int a = 5;
// a = "Hola"; // ERROR de compilación: No se puede asignar un String a una variable int.
String b = "Texto: ";
IO.println(b + a); // Concatenación implícita: convierte 'a' a String ("Texto: 5").
}
}
Una variable es una posición de memoria con un nombre simbólico asignado donde se almacena un valor susceptible de cambiar a lo largo del programa. Una constante, por el contrario, mantiene un valor fijo e inmutable durante toda la ejecución.
Para utilizar una variable en Java debemos especificar su tipo de dato seguido de su nombre (identificador). Podemos reservar el espacio en memoria (declarar) y asignarle un valor (inicializar) en pasos separados o en una sola línea:
static void main() {
// 1. Declaración (reserva espacio en memoria, sin valor inicial)
int edad;
// 2. Inicialización (asignación del primer valor)
edad = 25;
// 3. Declaración e inicialización simultánea (lo más habitual)
double precio = 19.99;
boolean activo = true;
}
Java maneja 8 tipos de datos primitivos que representan valores simples (enteros, decimales, caracteres o booleanos).
| Tipo | Tamaño (bits) | Descripción | Valor por defecto |
|---|---|---|---|
byte | 8 | Entero muy pequeño con signo $[-128, 127]$ | $0$ |
short | 16 | Entero corto con signo $[-32768, 32767]$ | $0$ |
int | 32 | Entero estándar $[-2^{31}, 2^{31}-1]$ | $0$ |
long | 64 | Entero largo $[-2^{63}, 2^{63}-1]$ | $0L$ |
float | 32 | Decimal en coma flotante de precisión simple | $0.0f$ |
double | 64 | Decimal en coma flotante de precisión doble | $0.0d$ |
char | 16 | Carácter individual en formato Unicode | $'\u0000'$ |
boolean | 1 | Valor lógico (true o false) | false |
El tipo String no es un tipo primitivo, sino una clase que representa secuencias de caracteres delimitadas por comillas dobles (“…”). En Java, las instancias de String son inmutables: cualquier modificación sobre un String genera un objeto nuevo en memoria.
Desde Java 10, es posible omitir la declaración explícita del tipo en variables locales utilizando la palabra reservada var. El compilador deducirá el tipo basándose en el valor asignado:
var edad = 25; // Compila como int var sueldo = 1250.50; // Compila como double var texto = "Hola"; // Compila como String
int y los decimales como double. Si necesitas asignar un valor de tipo float o long, debes añadir un sufijo al literal:
float pi = 3.1416f; // Requiere 'f' para no ser tratado como double long distancia = 3000000000L; // Requiere 'L'
Cuando necesitamos convertir el valor de un tipo primitivo a otro, utilizamos la conversión explícita mediante el operador de cast: (tipo) expresion.
public class Cast {
static void main() {
// Cast directo (truncamiento)
double precioDouble = 19.99;
int precioEntero = (int) precioDouble; // Pierde los decimales -> 19
// Evitar división entera no deseada
int a = 9;
int b = 2;
float resultadoIncorrecto = (float) (a / b); // Divide como int (4) y lo convierte a float -> 4.0f
float resultadoCorrecto = (float) a / b; // Convierte 'a' a float (9.0f) y divide -> 4.5f
}
}
(tipo) solo funciona entre tipos primitivos compatibles. Para convertir de String a un tipo numérico, debemos usar los métodos parse de sus respectivas clases envoltorio (*wrapper classes*):
String textoNumero = "42";
int numero = Integer.parseInt(textoNumero);
double decimal = Double.parseDouble("3.14");
_) y el símbolo de dólar ($)._ o $. Nunca por un número.int, class, final, public, if, etc.).distanciaKilometros antes que d.alturaEdificio).
Las constantes almacenan información que no debe cambiar durante la ejecución. Se definen anteponiendo la palabra reservada final. Por convención, sus nombres se escriben en MAYÚSCULAS_CON_GUION_BAJO.
public class Constantes {
static void main() {
final double VELOCIDAD_LUZ = 299792.458; // en km/s
final float PI = 3.1416f;
// VELOCIDAD_LUZ = 300000.0; // ERROR de compilación: No se puede reasignar una variable final
}
}
El operador principal de asignación es el signo igual (=). Según el tipo de dato asignado, debemos considerar ciertas reglas sintácticas:
char utilizan comillas simples ('a').String utilizan comillas dobles ("Hola").String, se utiliza la barra invertida (\) como carácter de escape.
satic void main() {
char letra = 'A';
boolean activo = true;
String frase = "Dijo: \"Hola mundo\""; // Carácter de escape \"
}
Java ofrece operadores aritméticos básicos: suma (+), resta (-), multiplicación (*), división (/) y módulo o resto entero (%). Pueden combinarse con el operador de asignación para acortar instrucciones:
| Operador | Ejemplo | Equivalencia |
|---|---|---|
+= | a += b; | a = a + b; |
-= | a -= b; | a = a - b; |
*= | a *= b; | a = a * b; |
/= | a /= b; | a = a / b; |
%= | a %= b; | a = a % b; |
Operan sobre un único valor para modificar su signo, incrementarlo, decrementarlo o negarlo:
+, -): Cambia o mantiene el signo del valor evaluado.++, –):a++): Utiliza el valor actual de la variable en la expresión y después la incrementa en 1.++a): Incrementa la variable en 1 antes de evaluar la expresión.!): Invierte un valor booleano (!true es false).
public class OperadoresUnarios {
static void main() {
int a = 3;
IO.println("Post-incremento (a++): " + a++); // Muestra 3, 'a' pasa a ser 4
IO.println("Valor tras a++: " + a); // Muestra 4
a = 3;
IO.println("Pre-incremento (++a): " + ++a); // 'a' pasa a ser 4, Muestra 4
}
}
Comparan dos operandos y devuelven un valor booleano (true o false): == (igual a), != (distinto de), < (menor que), > (mayor que), ⇐ (menor o igual) y >= (mayor o igual).
=) con la comparación de igualdad (==):
int a = 5; int b = 2; // IO.println(a = b); // Asigna 2 a 'a' e imprime 2. ¡Sobrescribe la variable! IO.println(a == b); // Compara si 'a' es igual a 'b' e imprime false.
Permiten combinar múltiples condiciones booleanas:
&& (AND): Devuelve true solo si ambas condiciones son verdaderas.|| (OR): Devuelve true si al menos una de las condiciones es verdadera.! (NOT): Niega la condición evaluada.
static void main() {
int edad = 20;
boolean tieneCarnet = true;
boolean puedeConducir = edad >= 18 && tieneCarnet; // true
}
En Java 25 utilizamos la clase IO para interactuar con la consola sin necesidad de realizar importaciones adicionales.
IO.println(…): Imprime el mensaje introducido y añade un salto de línea final.IO.print(…): Imprime el mensaje manteniendo el cursor en la misma línea.
El método IO.readln() pausa la ejecución hasta que el usuario escribe un texto y pulsa Intro. Siempre retorna los datos en forma de cadena (String). Si se requiere un valor numérico, debemos realizar el parseo correspondiente:
public class EntradaSalida {
static void main() {
String nombre = IO.readln("Introduce tu nombre: ");
int edad = Integer.parseInt(IO.readln("Introduce tu edad: "));
IO.println("Hola " + nombre + ", tienes " + edad + " años.");
}
}
Las cadenas de texto cuentan con métodos integrados para consultar y manipular su contenido:
length(): Devuelve el número de caracteres de la cadena.charAt(int index): Devuelve el carácter ubicado en el índice indicado (empezando en $0$).substring(int beginIndex, int endIndex): Extrae una subcadena desde beginIndex hasta endIndex - 1.indexOf(String str): Retorna la posición de la primera ocurrencia del texto buscado (o $-1$ si no existe).toUpperCase() / toLowerCase(): Convierte el texto a mayúsculas o minúsculas.trim() / strip(): Elimina los espacios en blanco iniciales y finales.equals(String str): Compara si dos cadenas tienen el mismo contenido. Nunca se debe usar == para comparar el texto de dos String.
static void main() {
String texto = " Hola Mundo ";
IO.println(texto.length()); // 14
IO.println(texto.trim().toUpperCase()); // "HOLA MUNDO"
IO.println(texto.contains("Mundo")); // true
}
La biblioteca estándar proporciona la clase Math con utilidades matemáticas estáticas de uso directo:
Math.sqrt(double a): Calcula la raíz cuadrada.Math.pow(double a, double b): Eleva la base a al exponente b.Math.abs(int a): Devuelve el valor absoluto.
Para generar números aleatorios se puede emplear Math.random() (retorna un double entre $0.0$ e $1.0$) o la clase java.util.Random:
static void main() {
double raiz = Math.sqrt(16); // 4.0
double potencia = Math.pow(2, 3); // 8.0
// Aleatorio entre 0 y 9 con Math.random()
int aleatorio = (int) (Math.random() * 10);
}
Crea un programa que calcule el área de un triángulo con base $5$ y altura $10$ ($\text{Área} = \frac{\text{base} \cdot \text{altura}}{2}$). La base y la altura deben ser constantes de tipo entero (int) y el área una variable del mismo tipo.
Modifica el tipo de la variable área a float y la altura a $9$. Comprueba si el resultado coincide con el cálculo manual. Haz las modificaciones necesarias en la operación sin cambiar el tipo de las constantes para obtener el resultado decimal exacto.
Modifica las constantes del Ejercicio 1.a a tipo decimal (float o double) para obtener la solución exacta directamente.
Haz que la base y la altura sean introducidas dinámicamente por el usuario a través de teclado mediante IO.readln().
Escribe un programa que solicite dos números decimales (float) al usuario e imprima su suma, resta, multiplicación, división y módulo (resto).
Modifica el programa anterior para que los resultados de las operaciones se muestren convertidos a entero (int) mediante *casting*, sin cambiar el tipo original de las variables de entrada.
Utiliza el método de formateo String.format(“%.2f”, valor) para mostrar el resultado de la división con exactamente dos decimales.
Crea un programa que solicite un número al usuario y calcule su raíz cuadrada empleando el método adecuado de la clase Math.
Aplica formato a la salida del ejercicio anterior para presentar la raíz cuadrada con tres decimales.
Escribe un programa que solicite por teclado una base y un exponente (números enteros) y muestre por pantalla el resultado de elevar la base a dicho exponente empleando la clase Math. Muestra el resultado formateado a 2 decimales.
Dado el siguiente literal de cadena con espacios superfluos: String mensaje = “ hola mundo ”;, crea un programa que imprima dicho mensaje completamente en mayúsculas y habiendo eliminado los espacios sobrantes de los extremos.
Utiliza la clase java.util.Random o Math.random() para generar y mostrar por pantalla un número entero aleatorio entre $0$ y $9$.
Modifica el ejercicio anterior para que el usuario introduzca por teclado el límite mínimo y máximo entre los cuales se generará el entero aleatorio.