UD02 · Elementos básicos de la programación
En la unidad anterior programaste sin escribir código. Aquí empieza Java de verdad: los datos que maneja un programa, las operaciones que se hacen con ellos y las estructuras que deciden qué se ejecuta y cuántas veces.
Es la unidad más densa del trimestre, y también la más rentable: todo lo que hay aquí lo vas a usar en cada programa que escribas durante el resto del ciclo, escribas en Java o en cualquier otro lenguaje.
Qué vas a aprender
Sección titulada «Qué vas a aprender»- Declarar variables y elegir bien el tipo de dato.
- Operar con esos datos y controlar las trampas de las conversiones de tipo.
- Leer datos del usuario y presentarlos con el formato que quieras.
- Tomar decisiones con
ifyswitch. - Repetir código con
while,do-whileyfor. - Trabajar con IntelliJ IDEA: crear un proyecto, ejecutarlo y depurarlo.
1. Ahora sí, el IDE
Sección titulada «1. Ahora sí, el IDE»Hasta ahora te ha bastado un editor de texto y un terminal. A partir de esta unidad los programas crecen, y con ellos la cantidad de tiempo que se pierde en cosas que una herramienta puede hacer por ti: avisarte de un error mientras escribes, completar nombres, buscar dónde se usa una variable o dejarte parar el programa a mitad para ver qué está pasando.
Vamos a usar IntelliJ IDEA Community Edition, que es gratuita y es el entorno más extendido en el mundo Java.
-
Descarga IntelliJ IDEA Community Edition desde la web de JetBrains. Cuidado con bajarte la Ultimate, que es de pago.
-
Al crear un proyecto nuevo, elige JDK 25. Si no aparece, desde el propio diálogo puedes descargarlo.
-
Escribe el código en el fichero
.javay ejecútalo con el botón ▶ del margen izquierdo, o conCtrl+Mayús+F10. -
La salida aparece abajo, en la ventana Run. Ahí es donde escribirás también cuando el programa pida datos.
Seguimos escribiendo programas con la sintaxis compacta de Java 25, la misma de la UD01:
void main() { IO.println("Empezamos la UD02");}2. Variables
Sección titulada «2. Variables»Un programa no es más que datos moviéndose. Y para manejar un dato hay que guardarlo en algún sitio con un nombre: eso es una variable.
Variable: un espacio en la memoria del ordenador, con un nombre y un tipo, cuyo contenido puede cambiar durante la ejecución del programa.
Piensa en una taquilla de un gimnasio. La taquilla tiene un número (el nombre), un tamaño que limita lo que cabe dentro (el tipo) y un contenido que puedes cambiar cuando quieras (el valor).
En Java, antes de usar una variable hay que declararla, diciendo de qué tipo
es. Después se le puede asignar un valor con =:
int edad; // declaraciónedad = 17; // asignaciónint cursos = 2; // declaración e inicialización, todo juntoCómo se llaman las variables
Sección titulada «Cómo se llaman las variables»Las reglas del lenguaje son pocas y de obligado cumplimiento:
- Pueden llevar letras, dígitos,
_y$, pero no pueden empezar por un dígito. - No pueden llevar espacios ni signos de puntuación.
- No pueden ser una palabra reservada del lenguaje (
int,class,for,if,new…). - Java distingue mayúsculas de minúsculas:
nota,NotayNOTAson tres variables diferentes.
Y luego están los convenios, que no son obligatorios para el compilador pero sí para cualquiera que trabaje contigo:
| Elemento | Convenio | Ejemplo |
|---|---|---|
| Variables y métodos | camelCase, empezando en minúscula |
notaMedia, precioSinIva |
| Constantes | Todo en mayúsculas, con _ |
IVA_GENERAL, AFORO_MAXIMO |
| Clases | PascalCase, empezando en mayúscula |
CuentaBancaria |
Un consejo que vale más que la tabla: el nombre tiene que decir qué guarda la
variable. n no dice nada; numeroDeAlumnos sí. Escribir un nombre largo
cuesta dos segundos gracias al autocompletado; entender dentro de un mes qué era
x2 cuesta mucho más.
3. Tipos de datos
Sección titulada «3. Tipos de datos»Java es un lenguaje fuertemente tipado: cada variable tiene un tipo, ese tipo se decide al declararla y no cambia. El compilador lo comprueba, y por eso caza errores antes de ejecutar nada.
Los tipos primitivos son ocho y son los ladrillos del lenguaje:
| Tipo | Guarda | Tamaño | Rango aproximado |
|---|---|---|---|
byte |
Enteros | 8 bits | −128 a 127 |
short |
Enteros | 16 bits | −32.768 a 32.767 |
int |
Enteros | 32 bits | ±2.147 millones |
long |
Enteros | 64 bits | ±9,2 trillones |
float |
Decimales | 32 bits | ~7 dígitos significativos |
double |
Decimales | 64 bits | ~15 dígitos significativos |
char |
Un carácter | 16 bits | 'a', 'ñ', '7', '€' |
boolean |
Cierto o falso | — | true o false |
En la práctica, el 90 % del tiempo vas a usar cuatro: int para enteros,
double para decimales, boolean para condiciones y char para caracteres
sueltos. Los demás aparecen cuando hay una razón concreta: long para
milisegundos o poblaciones, byte y short para ahorrar memoria en estructuras
muy grandes, float cuando la precisión no importa y el espacio sí.
Literales
Sección titulada «Literales»Un literal es un valor escrito tal cual en el código. Cada tipo tiene su forma:
int edad = 17;long milisegundos = 1298332800000L; // la L es obligatoria: no cabe en un intdouble precio = 10.5;float altura = 1.75f; // la f es obligatoria: si no, es doublechar inicial = 'C'; // comillas simplesboolean aprobado = true;String nombre = "Lucía"; // comillas dobles
int millon = 1_000_000; // los _ solo ayudan a leer, no cambian nadaint binario = 0b1010; // 10 en binarioint hexadecimal = 0xFF; // 255 en hexadecimalConstantes
Sección titulada «Constantes»Cuando un valor no debe cambiar, se declara con final. Si alguien intenta
modificarlo, el programa ni siquiera compila:
final double IVA = 0.21;final int AFORO = 540;
IVA = 0.10; // ✗ error de compilaciónÚsalas siempre que un número tenga significado propio. Un 540 suelto en mitad
del código no le dice nada a nadie; AFORO sí. Y si el aforo cambia, se toca en
un sitio y no en catorce.
var: cuando el tipo es evidente
Sección titulada «var: cuando el tipo es evidente»Desde Java 10 puedes declarar variables locales con var y dejar que el
compilador deduzca el tipo a partir del valor:
var nombre = "Lucía"; // Stringvar edad = 17; // intvar nota = 8.75; // doubleOjo con la confusión clásica: var no es que la variable no tenga tipo. Lo
tiene, se decide al declararla y no cambia. Esto sigue siendo un error:
var edad = 17;edad = "diecisiete"; // ✗ error: edad es int para siempreUsa var cuando el tipo se lea en la misma línea (var nombre = "Lucía"), y
escríbelo cuando no (double total = calcular();). La regla es que quien lea el
código sepa qué hay dentro sin tener que investigar.
Primitivos y referenciados
Sección titulada «Primitivos y referenciados»Los ocho tipos de la tabla son primitivos: la variable contiene el valor. El resto de tipos de Java son referenciados: la variable no contiene el objeto, sino la dirección donde está.
El referenciado que vas a usar desde el primer día es String:
String saludo = "Hola";Dos consecuencias prácticas que hay que saber ya:
Un referenciado puede estar vacío del todo. Eso se llama null y significa
«esta variable no apunta a nada». Un primitivo nunca puede ser null: un int
sin inicializar vale 0.
Los String no se comparan con ==. Esto es la fuente de errores número uno
de todo primero de DAM:
String a = IO.readln("Escribe hola: ");
if (a == "hola") { ... } // ✗ compara direcciones de memoriaif (a.equals("hola")) { ... } // ✓ compara el contenidoCon == estás preguntando «¿son el mismo objeto?»; con .equals() preguntas
«¿dicen lo mismo?». Casi siempre quieres lo segundo. Y si además da igual que se
escriba en mayúsculas, tienes equalsIgnoreCase.
Otras operaciones con cadenas que te harán falta enseguida:
String texto = "Programación";
texto.length() // 12 — cuántos caracteres tienetexto.toUpperCase() // "PROGRAMACIÓN"texto.toLowerCase() // "programación"texto.charAt(0) // 'P' — el carácter de la posición 0texto.substring(0, 4) // "Prog" — desde la 0 hasta la 4 sin incluirlatexto.trim() // quita los espacios de los extremostexto.isEmpty() // ¿está vacío?4. Entrada y salida por consola
Sección titulada «4. Entrada y salida por consola»Un programa que no habla con nadie sirve de poco. En Java 25 la entrada y la
salida básicas están en la clase IO:
IO.println("Hola"); // escribe y salta de líneaIO.print("Sin salto de línea"); // escribe y se queda ahíString nombre = IO.readln("¿Cómo te llamas? "); // pregunta y lee la respuestaLeer números
Sección titulada «Leer números»IO.readln() siempre devuelve texto, aunque el usuario escriba 42. Para
poder operar hay que convertirlo:
int edad = Integer.parseInt(IO.readln("¿Cuántos años tienes? "));double nota = Double.parseDouble(IO.readln("Dime tu nota: "));
IO.println("El año que viene tendrás " + (edad + 1));Si el usuario escribe hola donde esperabas un número, parseInt revienta con
un error en tiempo de ejecución. Controlar eso con elegancia se hace con
excepciones, y llega en la UD04; de momento nos fiamos.
Dar formato a la salida
Sección titulada «Dar formato a la salida»Concatenar con + funciona, pero se vuelve ilegible enseguida. Para salidas con
formato tienes formatted:
double total = 1234.5678;
IO.println("Total: " + total); // Total: 1234.5678IO.println("Total: %.2f €".formatted(total)); // Total: 1234,57 €IO.println("%-15s%5d".formatted("Camisetas", 3)); // texto a la izquierda, número a la derechaLos marcadores más útiles:
| Marcador | Sirve para | Ejemplo |
|---|---|---|
%d |
Enteros | %d → 42 |
%f |
Decimales | %.2f → 3,14 |
%s |
Texto | %s → Lucía |
%n |
Salto de línea | |
%-10s |
Texto ajustado a 10 a la izquierda | Para tablas |
%8.2f |
Decimal en 8 huecos, con 2 decimales | Para columnas de precios |
También tienes secuencias de escape dentro de las cadenas: \n salta de
línea, \t mete un tabulador, \" escribe una comilla y \\ una barra.
Y para textos de varias líneas, los bloques de texto evitan el festival de
\n:
IO.println(""" ========================== AUDITORIO DE MARTOS ========================== """);5. Operadores
Sección titulada «5. Operadores»Aritméticos
Sección titulada «Aritméticos»| Operador | Operación | Ejemplo |
|---|---|---|
+ |
Suma | 7 + 2 → 9 |
- |
Resta | 7 - 2 → 5 |
* |
Multiplicación | 7 * 2 → 14 |
/ |
División | 7 / 2 → 3 |
% |
Resto (módulo) | 7 % 2 → 1 |
Fíjate en la división, porque es la trampa más repetida del curso:
int a = 7, b = 2;IO.println(a / b); // 3 ¡división entera!IO.println(7.0 / 2); // 3.5 basta con que uno sea decimalIO.println((double) a / b); // 3.5 forzando la conversiónSi los dos operandos son enteros, el resultado es entero y la parte decimal se tira a la basura. No se redondea: se trunca.
El operador % parece menor y lo vas a usar constantemente: n % 2 == 0
detecta los pares, n % 5 == 0 los múltiplos de cinco, y n % 10 te da la
última cifra de un número.
Asignación e incremento
Sección titulada «Asignación e incremento»contador += 5; // equivale a contador = contador + 5precio *= 1.21; // y así con -=, /=, %=contador++; // suma 1contador--; // resta 1Relacionales
Sección titulada «Relacionales»Devuelven true o false: == (igual), != (distinto), >, <, >=, <=.
Recuerda que para comparar cadenas no se usa ==, sino .equals().
Lógicos
Sección titulada «Lógicos»Combinan condiciones: && (y), || (o), ! (no).
if (edad >= 18 && tieneCarnet) { ... }if (dia == 6 || dia == 7) { ... }if (!aprobado) { ... }Estos dos operadores son de cortocircuito: si la primera parte de un && es
falsa, Java ni evalúa la segunda, porque el resultado ya no puede cambiar. Eso no
es un detalle académico, es lo que permite escribir con seguridad:
if (divisor != 0 && total / divisor > 10) { ... }El operador ternario
Sección titulada «El operador ternario»Es un if en una línea, cuando lo único que quieres es elegir entre dos valores:
int mayor = (a > b) ? a : b;String mensaje = (nota >= 5) ? "Aprobado" : "Suspenso";Léelo como: ¿condición? entonces esto : si no, esto otro. Está bien para casos
cortos; si empiezas a anidar ternarios, usa un if y hazle un favor a quien lea
el código.
Precedencia
Sección titulada «Precedencia»Java sigue las reglas de siempre: primero *, / y %; después + y -;
luego las comparaciones; al final los lógicos. Y los paréntesis mandan sobre
todo lo demás.
En la duda, pon paréntesis. No cuestan nada y evitan discusiones:
double media = nota1 + nota2 + nota3 / 3; // ✗ solo divide la terceradouble media = (nota1 + nota2 + nota3) / 3; // ✓6. Conversiones de tipo
Sección titulada «6. Conversiones de tipo»A veces hay que pasar un dato de un tipo a otro. Java distingue dos casos.
Conversión implícita (ensanchamiento). Va de un tipo pequeño a uno más grande, no se pierde nada, y Java la hace sola:
int entero = 7;double decimal = entero; // 7.0, sin avisarConversión explícita (casting). Va de grande a pequeño, puede perder información, y por eso hay que pedirla a mano:
double precio = 10.99;int truncado = (int) precio; // 10, la parte decimal se pierdeEl orden de menor a mayor es: byte → short → int → long → float →
double. Hacia la derecha es automático; hacia la izquierda hay que forzarlo y
asumir las consecuencias.
Y un caso aparte: convertir texto a número no es un casting, porque un
String no es un número disfrazado. Hay que parsearlo:
int n = Integer.parseInt("42"); // ✓double d = Double.parseDouble("3.14"); // ✓int mal = (int) "42"; // ✗ ni compilaAl revés es más fácil, porque cualquier cosa concatenada con una cadena se convierte a texto:
String texto = "" + 42; // "42"String otro = String.valueOf(42); // "42", más explícito7. Comentarios
Sección titulada «7. Comentarios»// Comentario de una línea
/* Comentario de varias líneas*/
/** * Comentario de documentación (Javadoc). * Con este se genera la documentación del programa. Lo veremos en la UD04. */Ahora bien, comentar no es narrar lo que ya se ve:
contador++; // suma uno al contador ← inútilUn comentario bueno explica por qué, no qué:
// El aforo se reduce en 20 butacas: la última fila la ocupa el equipo técnico.final int AFORO = 520;Si sientes que necesitas un comentario para explicar qué hace un trozo de código, casi siempre la solución mejor es ponerle mejores nombres a las variables.
8. Estructuras de selección
Sección titulada «8. Estructuras de selección»Hasta ahora tus programas se ejecutaban en línea recta. Las estructuras de control son las que permiten decidir y repetir, y con ellas ya puedes escribir cualquier programa.
if / else
Sección titulada «if / else»int nota = Integer.parseInt(IO.readln("Nota: "));
if (nota >= 5) { IO.println("Aprobado");} else { IO.println("Suspenso");}Cuando hay más de dos caminos, se encadenan. El orden importa: se comprueban de arriba abajo y se ejecuta el primero que se cumple.
if (nota < 5) { IO.println("Insuficiente");} else if (nota < 6) { IO.println("Suficiente");} else if (nota < 7) { IO.println("Bien");} else if (nota < 9) { IO.println("Notable");} else { IO.println("Sobresaliente");}Cuando lo que haces es comparar una misma variable con varios valores
concretos, el switch se lee mucho mejor que quince else if. En Java
moderno se escribe con flechas y no necesita break:
int dia = Integer.parseInt(IO.readln("Día de la semana (1-7): "));
switch (dia) { case 1 -> IO.println("Lunes"); case 2 -> IO.println("Martes"); case 3 -> IO.println("Miércoles"); case 4 -> IO.println("Jueves"); case 5 -> IO.println("Viernes"); case 6, 7 -> IO.println("Fin de semana"); default -> IO.println("Ese día no existe");}Mejor todavía: en Java el switch puede ser una expresión, es decir, puede
devolver un valor directamente:
String nombreDia = switch (dia) { case 1 -> "Lunes"; case 2 -> "Martes"; case 3 -> "Miércoles"; case 4 -> "Jueves"; case 5 -> "Viernes"; case 6, 7 -> "Fin de semana"; default -> "Día no válido";};
IO.println(nombreDia);9. Estructuras de repetición
Sección titulada «9. Estructuras de repetición»Repite mientras se cumpla una condición. Se comprueba antes de entrar, así que puede no ejecutarse ninguna vez:
int intentos = 0;
while (intentos < 4) { String clave = IO.readln("Combinación: "); if (clave.equals("1234")) { IO.println("La caja fuerte se ha abierto"); break; } intentos++;}Es la estructura adecuada cuando no sabes cuántas vueltas vas a dar: hasta que el usuario acierte, hasta que meta un número negativo, hasta que se acabe el fichero.
do-while
Sección titulada «do-while»Igual, pero la condición se comprueba al final, así que el cuerpo se ejecuta al menos una vez. Es lo que quieres en los menús:
int opcion;
do { IO.println(""" 1. Vender entradas 2. Consultar evento 3. Salir """); opcion = Integer.parseInt(IO.readln("Opción: "));
switch (opcion) { case 1 -> IO.println("Vendiendo…"); case 2 -> IO.println("Consultando…"); case 3 -> IO.println("Hasta luego"); default -> IO.println("Opción no válida"); }} while (opcion != 3);Cuando sí sabes cuántas vueltas vas a dar, el for reúne en una sola línea
las tres cosas que gobiernan el bucle:
for (int i = 1; i <= 10; i++) { IO.println(i + " x 3 = " + (i * 3));}- Inicialización (
int i = 1): se ejecuta una vez, al principio. - Condición (
i <= 10): se comprueba antes de cada vuelta. - Actualización (
i++): se ejecuta al final de cada vuelta.
Cualquier for se puede escribir como un while y al revés. Se usa el for
cuando hay un contador claro, porque tenerlo todo junto en una línea evita
olvidos.
Los bucles se pueden anidar, y ahí es donde empieza lo interesante. Una pirámide de asteriscos es exactamente eso: un bucle de filas, y dentro, uno de columnas.
int altura = 5;
for (int fila = 1; fila <= altura; fila++) { for (int columna = 1; columna <= fila; columna++) { IO.print("*"); } IO.println();}break y continue
Sección titulada «break y continue»break sale del bucle inmediatamente. continue salta el resto de la vuelta
actual y pasa a la siguiente.
for (int i = 1; i <= 100; i++) { if (i % 3 == 0) continue; // los múltiplos de 3 se saltan if (i > 50) break; // pasado el 50, se acabó IO.println(i);}Son cómodos, pero conviene no abusar: un bucle con cuatro break repartidos es
difícil de seguir. Si la condición de salida es importante, casi siempre queda
más claro en el while.
10. Material complementario
Sección titulada «10. Material complementario»Para la práctica de esta unidad vas a necesitar trabajar con fechas: calcular cuántos días faltan para un evento y comprobar si estás dentro del periodo de descuento.
Lo esencial, para que te suene:
import java.time.LocalDate;import java.time.temporal.ChronoUnit;
void main() { LocalDate hoy = LocalDate.now(); LocalDate evento = LocalDate.of(2024, 11, 20);
long dias = ChronoUnit.DAYS.between(hoy, evento); IO.println("Faltan " + dias + " días");}11. Trabaja con la IA
Sección titulada «11. Trabaja con la IA»Pídele a una IA que te resuelva esto:
Programa en Java que pida dos números por teclado y diga cuál es mayor.
Analiza lo que te devuelva y responde:
- ¿Ha usado
ScanneroIO.readln? ¿Por qué crees que ha elegido eso? - ¿Ha cerrado el
Scanner? ¿Sabrías decir qué pasa si no se cierra? - ¿Compara los números con
==, o con>? ¿Y si en vez de números fueran textos? - Pídele que lo reescriba con la sintaxis compacta de Java 25. ¿Lo consigue a la primera?
Currículo oficial del módulo
Resultados de aprendizaje y criterios de evaluación que se trabajan en esta unidad, según la ORDEN de 16 de junio de 2011 (BOJA núm. 142). Ver el mapa completo del módulo.
Las estructuras de control (selección, repetición y salto) se trabajan en esta unidad, no en la UD04: así lo hace el material de clase, aunque la programación didáctica las sitúe más adelante. La UD04 retoma el RA3 con el control de excepciones, las pruebas y la documentación.
RA1Reconoce la estructura de un programa informático, identificando y relacionando los elementos propios del lenguaje de programación utilizado.
- a) Se han identificado los bloques que componen la estructura de un programa informático.
- b) Se han creado proyectos de desarrollo de aplicaciones.
- c) Se han utilizado entornos integrados de desarrollo.
- d) Se han identificado los distintos tipos de variables y la utilidad específica de cada uno.
- e) Se ha modificado el código de un programa para crear y utilizar variables.
- f) Se han creado y utilizado constantes y literales.
- g) Se han clasificado, reconocido y utilizado en expresiones los operadores del lenguaje.
- h) Se ha comprobado el funcionamiento de las conversiones de tipos explícitas e implícitas.
- i) Se han introducido comentarios en el código.
RA2Escribe y prueba programas sencillos, reconociendo y aplicando los fundamentos de la programación orientada a objetos.
- b) Se han escrito programas simples.
RA3Escribe y depura código, analizando y utilizando las estructuras de control del lenguaje.
- a) Se ha escrito y probado código que haga uso de estructuras de selección.
- b) Se han utilizado estructuras de repetición.
- c) Se han utilizado estructuras de repetición.
- d) Se han reconocido las posibilidades de las sentencias de salto.
- f) Se han creado programas ejecutables utilizando diferentes estructuras de control.
- g) Se han probado y depurado los programas.
- h) Se ha comentado y documentado el código.
RA5Realiza operaciones de entrada y salida de información, utilizando procedimientos específicos del lenguaje y librerías de clases.
- a) Se ha utilizado la consola para realizar operaciones de entrada y salida de información.
- b) Se han aplicado formatos en la visualización de la información.
© 2026 Carlos Barroso · Contenido bajo CC BY-NC-SA 4.0

