Tabla de Contenidos

02.2 - Elementos básicos de Java

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.

1. Tipado de lenguajes

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").
    }
}

2. Definición y tipos de datos

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.

Declaración e inicializació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;
}

En Java, las variables locales deben inicializarse antes de ser utilizadas. Intentar leer o imprimir el valor de una variable que no ha sido inicializada provocará un error de compilación.

Tipos primitivos

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

Cadenas de texto: Clase String

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.

Inferencia de tipos (var)

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

Por defecto, Java interpreta los literales enteros como 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'

Conversión de tipos (Cast)

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
    }
}

El operador (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");

Nombres y reglas de estilo

Reglas de sintaxis

Buenas prácticas

3. Constantes

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
    }
}

4. Operadores

Operador de asignación y caracteres de escape

El operador principal de asignación es el signo igual (=). Según el tipo de dato asignado, debemos considerar ciertas reglas sintácticas:

satic void main() {
    char letra = 'A';
    boolean activo = true;
    String frase = "Dijo: \"Hola mundo\""; // Carácter de escape \"
}

Operadores aritméticos y de asignación compuesta

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;

Operadores unarios

Operan sobre un único valor para modificar su signo, incrementarlo, decrementarlo o negarlo:

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
    }
}

Operadores relacionales

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).

Un error muy frecuente es confundir la asignación (=) 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.

Operadores lógicos

Permiten combinar múltiples condiciones booleanas:

static void main() {
    int edad = 20;
    boolean tieneCarnet = true;

    boolean puedeConducir = edad >= 18 && tieneCarnet; // true
}

5. Entrada y Salida de datos con la clase IO

En Java 25 utilizamos la clase IO para interactuar con la consola sin necesidad de realizar importaciones adicionales.

Salida por consola

Entrada por teclado

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.");
    }
}

6. Utilidades frecuentes: Métodos de String y Math

Métodos principales de la clase String

Las cadenas de texto cuentan con métodos integrados para consultar y manipular su contenido:

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
}

Métodos matemáticos (Clase Math y Random)

La biblioteca estándar proporciona la clase Math con utilidades matemáticas estáticas de uso directo:

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);
}

Ejercicios

Ejercicio 1.a

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.

Ejercicio 1.b

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.

Ejercicio 1.c

Modifica las constantes del Ejercicio 1.a a tipo decimal (float o double) para obtener la solución exacta directamente.

Ejercicio 1.d

Haz que la base y la altura sean introducidas dinámicamente por el usuario a través de teclado mediante IO.readln().

Ejercicio 2.a

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).

Ejercicio 2.b

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.

Ejercicio 2.c

Utiliza el método de formateo String.format(“%.2f”, valor) para mostrar el resultado de la división con exactamente dos decimales.

Ejercicio 3.a

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.

Ejercicio 3.b

Aplica formato a la salida del ejercicio anterior para presentar la raíz cuadrada con tres decimales.

Ejercicio 4

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.

Ejercicio 5

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.

Ejercicio 6.a

Utiliza la clase java.util.Random o Math.random() para generar y mostrar por pantalla un número entero aleatorio entre $0$ y $9$.

Ejercicio 6.b

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.