3. Estructura de un programa Java
UD1 — Fundamentos de Programación
IES Thiar · Curso 2026 - 2027
| Aspecto | Valor |
|---|---|
| Resultado de aprendizaje | RA1 — Reconoce la estructura de un programa informático, identificando y relacionando los elementos propios del lenguaje de programación utilizado. |
| Criterios de evaluación cubiertos | CE 1.1 — Se han identificado los bloques que componen la estructura de un programa informático. CE 1.9 — Se han introducido comentarios en el código. |
| Marco normativo | RD 405/2023 · RD 450/2010 · RD 659/2023 |
| Tecnología base | Java 25 LTS — implicitly declared classes e instance main methods estables (JEP 512: Compact Source Files and Instance Main Methods). |
Introducción de la sección
En la Sección 2 escribiste tu primer programa Java 25 con cuatro líneas y la verdad es que no te expliqué qué significaba casi nada de lo que pusiste. Esa era la idea: primero pruebes que el entorno funciona y luego, una vez has visto que un void main() es capaz de imprimir "Hola, mundo", entenderemos qué pinta tiene un programa Java por dentro, palabra por palabra. Esta es la sección en la que eso ocurre.
El objetivo es que al terminar sepas descomponer cualquier programa Java sencillo en sus piezas: la clase (que en Java 25 puede ser implícita), el método main (que es la puerta de entrada), las instrucciones de salida por consola (println, print, printf), las reglas sintácticas que no puedes saltarte (punto y coma, llaves, sensibilidad a mayúsculas), los tres tipos de comentarios que admite el lenguaje y las convenciones de nomenclatura que todo programador Java respeta. Verás también los cinco o seis errores que comete el 99% de los principiantes en sus primeros días, para que los reconozcas en cuanto el compilador te los escupa a la cara. Cuando acabes, leer el App.java de la Sección 2 te parecerá trivial.
3.1 Elementos léxicos del lenguaje Java: el mapa antes del territorio
Antes de abrir el capó de un programa Java y mirar el motor (la clase, el método main, las instrucciones de salida), conviene ver el mapa completo de las piezas que puedes encontrar. Un programa Java está construido a partir de seis categorías de elementos léxicos: palabras reservadas, identificadores, literales, separadores, operadores y comentarios. Conocer esta taxonomía te ahorrará confusión cuando, en las próximas secciones, veas aparecer cada uno por separado.
Analogía
Aprender un lenguaje de programación se parece a aprender un idioma natural. En español hay sustantivos, verbos, adjetivos, preposiciones y signos de puntuación; cada categoría tiene sus reglas. En Java pasa lo mismo: hay palabras reservadas (los verbos irregulares del lenguaje, que Java se reserva para sí mismo), identificadores (los sustantivos que tú eliges), literales (los valores concretos como 42 o "hola"), separadores (los signos de puntuación), operadores (las conjunciones que combinan valores) y comentarios (las acotaciones del autor que el compilador ignora). Saber qué categoría es cada cosa es la mitad del trabajo para entender un programa.
3.1.1 Palabras reservadas (keywords)
Las palabras reservadas son términos que el lenguaje Java usa para sí mismo y que tú no puedes usar como identificadores (nombres de variables, clases, métodos...). Java 25 tiene alrededor de 50 palabras reservadas, agrupadas por función:
| Categoría | Palabras |
|---|---|
| Tipos primitivos | byte, short, int, long, float, double, boolean, char |
| Control de flujo | if, else, switch, case, default, for, while, do, break, continue, return |
| Orientación a objetos | class, interface, enum, record, extends, implements, new, this, super, instanceof |
| Modificadores | public, protected, private, static, final, abstract, synchronized, volatile, transient, native, strictfp |
| Manejo de errores | try, catch, finally, throw, throws |
| Paquetes | package, import |
| Otros | void, assert, goto, const |
Cuidado
goto y const están reservadas pero no se usan en Java (existen por compatibilidad histórica con C/C++). Si intentas usarlas como identificadores, el compilador las rechaza.
Además, Java tiene palabras contextuales (restricted keywords) que solo son reservadas en ciertos contextos: var (desde Java 10), record (Java 16), sealed y permits (Java 17), yield (Java 14). Y los literales booleanos true, false y el literal nulo null también están reservados, aunque técnicamente no son keywords.
3.1.2 Identificadores
Un identificador es el nombre que tú eliges para una variable, constante, método, clase, paquete o parámetro. Debe cumplir dos reglas:
- Empezar por una letra (incluida la ñ y letras Unicode), un guion bajo
_o el símbolo dólar$. - Continuar con letras, dígitos, guiones bajos o dólares (sin espacios ni otros símbolos).
Pista
Aunque Java permite _ y $ en identificadores, las convenciones de Oracle los desaconsejan (excepto _ en constantes UPPER_SNAKE_CASE y $ en código generado automáticamente). Las convenciones de nomenclatura completas (camelCase, PascalCase, UPPER_SNAKE_CASE) se ven en la Sección 3.7 Convenciones de nomenclatura.
3.1.3 Literales
Un literal es un valor escrito directamente en el código: 42, 3.14, "hola", true, 'A'. Java tiene literales enteros, decimales, booleanos, de carácter y de cadena. Su tratamiento en profundidad (rangos, sufijos L/f/d, separador _, notación hexadecimal/binaria/octal) corresponde a la Sección 4 (Variables y tipos primitivos) y a la Sección 5 (El tipo String).
3.1.4 Separadores
Los separadores son símbolos que estructuran el código. Java tiene nueve:
| Símbolo | Uso típico |
|---|---|
( ) |
Delimitar parámetros, agrupar expresiones, llamadas a método |
{ } |
Delimitar bloques (clase, método, if, for...) |
[ ] |
Declarar y acceder a arrays |
; |
Finalizar una instrucción |
, |
Separar elementos (parámetros, declaraciones múltiples...) |
. |
Acceso a miembros (objeto.metodo(), Clase.CAMPO) |
... |
Varargs (parámetros de número variable) |
@ |
Anotaciones |
3.1.5 Operadores
Los operadores son símbolos que realizan operaciones sobre valores: +, -, *, /, ==, &&, ++, ?:, ::, ... Java tiene más de 40 operadores repartidos en categorías (aritméticos, relacionales, lógicos, bit a bit, asignación). Su tratamiento completo corresponde a la Sección 7 (Operadores).
3.1.6 Comentarios
Los comentarios son texto que el compilador ignora y que sirve para documentar el código. Java admite tres tipos: // (línea), /* */ (bloque) y /** */ (Javadoc). Se tratan en detalle en la Sección 3.6 Comentarios.
Mapa mental de los elementos léxicos
mindmap
root((Elementos léxicos<br/>de Java))
Palabras reservadas
Tipos primitivos
Control de flujo
OO (class, new, this)
Modificadores
Manejo de errores
Paquetes
Identificadores
Variables
Constantes
Métodos
Clases
Paquetes
Literales
Enteros
Decimales
Booleanos
Carácter
Cadena
Separadores
Paréntesis
Llaves
Corchetes
Punto y coma
Coma, punto
Operadores
Aritméticos
Relacionales
Lógicos
Bit a bit
Asignación
Comentarios
Línea
Bloque
Javadoc
3.2 De la clase clásica al main moderno: evolución del punto de entrada
La ceremonia histórica de Java
Si abres cualquier manual de Java escrito antes de 2024, tu primer programa se parecerá a este:
Cinco líneas, cuatro palabras clave raras (public, class, static, void), un nombre obligatorio (main), un parámetro obligatorio (String[] args) y una clase obligatoria con el mismo nombre que el fichero. Para alguien que nunca ha programado, eso es mucha ceremonia antes de poder imprimir "Hola". Históricamente, se ha pedido simplificar el primer contacto con el lenguaje, porque la curva de entrada era una de las cosas que alejaba a la gente de Java frente a Python.
La buena noticia es que, en Java 25, todo eso es opcional. El mismo programa se escribe ahora así:
Tres líneas, dos palabras clave (void, main), sin clase visible y sin parámetros. Esto es posible gracias a dos características que llegaron como preview en Java 21 (JEP 445) y se estabilizaron en Java 25 con el JEP 512: Compact Source Files and Instance Main Methods: las implicitly declared classes (clases declaradas implícitamente, también llamadas compact source files en la primera versión del JEP) y los instance main methods (métodos main de instancia, sin static). El compilador, por debajo, te envuelve todo en una clase implícita que toma el nombre del fichero; tú no la ves declarada, pero existe.
La evolución, en un diagrama
timeline
title Evolución del punto de entrada en Java
1996 (Java 1.0) : public static void main(String[] args) - Forma clásica obligatoria durante 27 años
2023 (Java 21 preview) : void main() - JEP 445 primera preview, opt-in
2024 (Java 22-23 preview) : void main() - Segunda y tercera preview con ajustes
2025 (Java 25 LTS) : void main() - ESTABLE (JEP 512), sin --enable-preview
Diagrama 3.1 — Evolución del método main en Java, desde la forma clásica de 1996 hasta la forma moderna estable de 2025.
¿Cuándo usar cada forma?
Esta es una pregunta con matices. La forma moderna void main() es perfecta para aprender, para programas pequeños, para ejemplos de documentación y para herramientas de prototipado. La forma clásica public static void main(String[] args) sigue siendo necesaria cuando:
- Estás escribiendo código que tiene que correr en versiones anteriores a Java 25 (por ejemplo, en una empresa que aún usa Java 17 LTS).
- El programa va a crecer y quieres declarar la clase explícitamente desde el principio para tenerlo todo organizado.
En este ciclo empezaremos con la forma moderna para que la curva de entrada sea suave, e iremos introduciendo la forma clásica cuando el contexto lo pida (a partir de UD4, cuando definamos clases propias con campos y métodos). Lo importante es que no hay una forma "incorrecta": ambas producen el mismo bytecode y se ejecutan igual.
Analogía
La forma clásica con public class es como escribir una carta formal con membrete, fecha, encabezado "Estimado Sr." y despedida "Atentamente". Es lo que toca en un contexto formal. La forma moderna void main() es como escribir un WhatsApp a un amigo: vas al grano, sin protocolo. Las dos comunican lo mismo; la diferencia es el contexto y la audiencia.
3.3 Anatomía de una clase y del método main
Vamos a despiezar el programa clásico pieza por pieza. Aunque en Java 25 puedas omitir la clase, conviene saber qué significaba cada palabra clave, porque en UD4 las vas a usar todas y porque el 90% del código Java que encuentres en internet y en empresas sigue la forma clásica.
flowchart TD
A["public class HolaMundo {"] --> B["public - la clase es visible desde cualquier otro paquete"]
A --> C["class - palabra clave para declarar una clase"]
A --> D["HolaMundo - nombre de la clase en PascalCase"]
A --> E["{ - abre el bloque de la clase"]
F["public static void main(String[] args) {"] --> G["public - el método es visible desde fuera"]
F --> H["static - método de clase, no necesita crear un objeto"]
F --> I["void - no devuelve ningún valor"]
F --> J["main - nombre obligatorio, lo busca la JVM"]
F --> K["String[] args - parámetros: argumentos de línea de comandos"]
F --> L["{ - abre el bloque del método"]
E -.->|contiene| F
L -.->|contiene| M["System.out.println(...);"]
M --> N["} - cierra el método"]
N --> O["} - cierra la clase"]
style A fill:#1565c0,color:#fff,stroke:#0d47a1
style F fill:#2e7d32,color:#fff,stroke:#1b5e20
style M fill:#e65100,color:#fff,stroke:#bf360c
style B fill:#e3f2fd,stroke:#1565c0,color:#000
style C fill:#e3f2fd,stroke:#1565c0,color:#000
style D fill:#e3f2fd,stroke:#1565c0,color:#000
style E fill:#e3f2fd,stroke:#1565c0,color:#000
style G fill:#e8f5e9,stroke:#2e7d32,color:#000
style H fill:#e8f5e9,stroke:#2e7d32,color:#000
style I fill:#e8f5e9,stroke:#2e7d32,color:#000
style J fill:#e8f5e9,stroke:#2e7d32,color:#000
style K fill:#e8f5e9,stroke:#2e7d32,color:#000
style L fill:#e8f5e9,stroke:#2e7d32,color:#000
Diagrama 3.2 — Anatomía completa de un programa Java clásico: cada palabra clave explicada.
La clase como contenedor obligatorio
En Java, todo el código ejecutable vive dentro de una clase. No existen funciones sueltas como en C o Python; cualquier instrucción que se ejecute tiene que estar dentro de un método, y cualquier método tiene que estar dentro de una clase. Esto es una decisión de diseño del lenguaje vinculada a su naturaleza 100% orientada a objetos. En Java 25, las implicitly declared classes simplemente ocultan esta clase de tu vista: el compilador la crea por ti, le pone como nombre el del fichero (por ejemplo, Main.java → clase Main) y la registra. Pero la clase existe.
| Palabra | Significado | ¿Obligatoria en Java 25 moderno? |
|---|---|---|
public |
Modificador de acceso: visible desde cualquier paquete | No (la clase implícita no es pública) |
class |
Palabra clave para declarar una clase | No (la añade el compilador) |
HolaMundo |
Nombre de la clase, debe coincidir con el nombre del fichero | No (clase implícita sin nombre) |
{ } |
Llaves que delimitan el bloque de la clase | Sí, aunque implícitas |
El método main como punto de entrada
El método main es la puerta de entrada que busca la JVM cuando ejecutas un programa. La JVM arranca, busca una clase (explícita o anónima) que tenga un método llamado main con una firma concreta, y empieza a ejecutar desde ahí. Si no lo encuentra, el programa no arranca.
| Palabra | Significado | ¿Obligatoria en Java 25 moderno? |
|---|---|---|
public |
El método es accesible desde la JVM (que está "fuera" de tu clase) | No (el launcher la infiere; se recomienda en forma clasica) |
static |
Método de clase, no requiere crear un objeto para llamarse | No (instance main) |
void |
El método no devuelve ningún valor | Sí |
main |
Nombre obligatorio, la JVM lo busca | Sí |
String[] args |
Parámetros: argumentos pasados por línea de comandos | Opcional |
{ } |
Llaves que delimitan el bloque del método | Sí |
Analogía
Imagina que tu programa es un edificio y la JVM es el repartidor que llega con un paquete. El repartidor no sabe por dónde entrar; busca una puerta con un cartel que diga "ENTRADA". En Java, ese cartel es la palabra main. Si no la encuentra, se da la vuelta y se va (y te muestra un error). El parámetro String[] args sería el portero que te pide el paquete de datos que has traído desde la línea de comandos; si no necesitas pasarle nada, puedes omitirlo en Java 25.
No te preocupes ahora por entender static a fondo: en UD4, cuando veamos clases y objetos, entenderás la diferencia entre métodos de clase (static) y métodos de instancia. Por ahora basta con que sepas que en Java 25 ya no hace falta para que main arranque.
La regla del nombre del fichero
Una regla que sí sigue vigente en Java 25: si declaras una clase public (es decir, escribes public class HolaMundo), el fichero donde vive debe llamarse exactamente HolaMundo.java, con las mismas mayúsculas y minúsculas. Si no coinciden, el compilador se queja. En cambio, con una implicitly declared class (sin public class explícito), el fichero debe llamarse igual que la clase implícita resultante (por ejemplo, Main.java produce una clase Main).
3.4 Salida por consola: println, print y printf
Ya sabes imprimir texto con System.out.println("Hola"). Vamos a ver las tres variantes que ofrece Java para sacar información por consola, porque cada una tiene su caso de uso y conviene elegir bien. Además, desde la versión 25, una de las aportaciones complementarias más importantes del JEP 512: la introducción de la clase utilitaria java.lang.IO que nos va a permitir usar la entrada y salida de la información de una forma más sencilla.
Las tres variantes
| Método | Qué hace | Salto de línea al final | Cuándo usar |
|---|---|---|---|
System.out.println(x)IO.println(x) |
Imprime x y salta de línea |
Sí | Caso general, mensajería simple |
System.out.print(x)IO.print(x) |
Imprime x sin saltar de línea |
No | Cuando quieres componer una línea en varios pasos |
System.out.printf(fmt, args) |
Imprime con formato (estilo C) | No (hay que añadir %n) |
Cuando necesitas alinear columnas, decimales, etc. |
println vs print
La diferencia entre println y print es solo el salto de línea final, pero cambia bastante el comportamiento:
Salida:
println sin argumentos es un truco útil cuando quieres un salto de línea "limpio" sin imprimir nada más.
printf: cuando necesitas formatear
printf (print formatted) es la opción potente para cuando necesitas controlar el formato: número de decimales, alineación, relleno con ceros, etc. Funciona con especificadores de formato que empiezan por %:
Salida:
Los especificadores más usados en este curso son:
| Especificador | Tipo | Ejemplo | Salida |
|---|---|---|---|
%s |
String | printf("Hola, %s", "Ana") |
Hola, Ana |
%d |
Entero (int, long) | printf("Edad: %d", 23) |
Edad: 23 |
%f |
Decimal (float, double) | printf("PI: %f", 3.14159) |
PI: 3,141590 |
%.2f |
Decimal con 2 decimales | printf("PI: %.2f", 3.14159) |
PI: 3,14 |
%n |
Salto de línea portable | printf("Línea%n") |
Línea + salto |
%% |
Un símbolo % literal |
printf("100%%") |
100% |
%5d |
Entero en 5 caracteres | printf("[%5d]", 42) |
[ 42] |
%-5d |
Entero en 5 caracteres, alineado a la izquierda | printf("[%-5d]", 42) |
[42 ] |
Info
Las veremos y usaremos poco a poco en las siguientes secciones.
Pista
En Java 15+ también tienes el método formatted sobre Strings, que es más legible cuando tienes varios valores: "Alumna: %s, edad: %d".formatted(nombre, edad). Internamente hace lo mismo que printf, pero devuelve el String en lugar de imprimirlo. Útil cuando quieres formatear sin imprimir todavía.
Cuidado con la coma decimal. En sistemas con locale español,
printfusa la coma como separador decimal (8,75); en sistemas con locale inglés, usa el punto (8.75). Si necesitas que el formato sea consistente independientemente del país, puedes forzar el locale:System.out.printf(java.util.Locale.US, "PI: %.2f", 3.14159)siempre produciráPI: 3.14.
3.5 Reglas sintácticas: mayúsculas, punto y coma, bloques
Java es un lenguaje de sintaxis estricta, lo que significa que el compilador no perdona casi nada. Esto asusta al principio, pero es una virtud: te obliga a ser preciso y te ahorra sorpresas en producción. Hay cuatro reglas que no puedes saltarte.
Regla 1: sensibilidad a mayúsculas y minúsculas
Java distingue entre mayúsculas y minúsculas en todo: nombres de variables, clases, métodos, palabras clave. edad, Edad y EDAD son tres identificadores distintos para Java. system.out.println no compila; tiene que ser System.out.println. Esto es lo primero que se le olvida a quien viene de Python o HTML, donde la cosa es más laxa.
| Código | ¿Compila? | Por qué |
|---|---|---|
System.out.println("hola") |
Sí | System con mayúscula inicial |
system.out.println("hola") |
No | system en minúscula no existe |
int edad = 18; System.out.println(Edad) |
No | Edad y edad son distintas |
public class Main en main.java |
No | La clase Main no coincide con el fichero main.java |
Regla 2: el punto y coma es obligatorio
Cada instrucción en Java debe terminar con punto y coma (;). Es como el punto y seguido en español: indica que la frase termina ahí. Si te dejas uno, el compilador te lo dirá con un mensaje tipo ';' expected. Si pones uno de más, también se queja.
Regla 3: los bloques se delimitan con llaves { }
Un bloque es un conjunto de instrucciones agrupadas entre llaves { y }. Los bloques definen el cuerpo de una clase, el cuerpo de un método, el cuerpo de un if, etc. Las llaves deben estar equilibradas: cada { tiene que tener su } correspondiente. IntelliJ te los marca en color y te permite saltar entre ellos con Ctrl+M (o Cmd+M en macOS).
Analogía
Las llaves son como las paredes de las habitaciones de una casa. La clase es la casa entera; el método main es una habitación dentro de la casa; el if es un armario dentro de la habitación. Cada { es una puerta que entra a un espacio más pequeño; cada } es la puerta que sale. Si te dejas una } sin cerrar, la "casa" se queda abierta y el compilador no sabe dónde termina cada cosa.
Regla 4: el espacio en blanco es libre (casi)
Java no le importa cuántos espacios o saltos de línea pongas entre tokens, salvo dentro de strings. Estos tres programas son equivalentes para el compilador:
Los tres compilan. El que tu profesor (y tus compañeros, y tú mismo dentro de tres meses) querrá leer es el segundo. Por eso existen convenciones de estilo: no son obligatorias para el compilador, pero sí para trabajar en equipo. En IntelliJ, Ctrl+Alt+L (o Cmd+Option+L en macOS) formatea el código automáticamente según las convenciones de Oracle.
3.6 Comentarios: //, /* */ y Javadoc /** */
Los comentarios son texto que el compilador ignora. Sirven para que tú (o quien venga detrás) entendáis qué hace el código y por qué. Java admite tres tipos, cada uno con su propósito.
flowchart LR
COM["Comentarios en Java"] --> LINE["// Comentario de línea"]
COM --> BLOCK["/* Comentario<br/>de bloque */"]
COM --> DOC["/** Comentario<br/>Javadoc */"]
LINE --> L1["Notas rápidas, aclaraciones puntuales"]
LINE --> L2["El más usado en el día a día"]
BLOCK --> B1["Varias líneas seguidas"]
BLOCK --> B2["Comentar código temporalmente (mejor evitarlo)"]
DOC --> D1["Documentación de API pública"]
DOC --> D2["Genera HTML con la herramienta javadoc"]
DOC --> D3["Soporta etiquetas: @param, @return, @author..."]
style COM fill:#1565c0,color:#fff,stroke:#0d47a1
style LINE fill:#e8f5e9,stroke:#2e7d32,color:#000
style BLOCK fill:#fff3e0,stroke:#e65100,color:#000
style DOC fill:#f3e5f5,stroke:#6a1b9a,color:#000
Diagrama 3.3 — Los tres tipos de comentarios en Java y sus casos de uso.
Comentario de línea: //
El más usado. Todo lo que va desde // hasta el final de la línea es ignorado por el compilador.
Comentario de bloque: /* ... */
Para comentarios que ocupan varias líneas. Puede ir en cualquier posición (incluso en medio de una línea, aunque no es recomendable).
Cuidado
No uses comentarios de bloque para "comentar" código que ya no quieres ejecutar. IntelliJ tiene un atajo mucho mejor: selecciona el código y pulsa Ctrl+/ (comentar/descomentar con //) o Ctrl+Shift+/ (con /* */). Y si el código ya no sirve, bórralo: para eso está git. Código comentado es ruido que confunde a quien lee.
Javadoc: /** ... */
Es un tipo especial de comentario que documenta tu código. Empieza con /** (doble asterisco) y contiene etiquetas como @param, @return, @author, @see, @throws. La herramienta javadoc (que viene con el JDK) procesa estos comentarios y genera documentación HTML navegable, como la del API oficial de Java.
No te agobies por las etiquetas: las verás en detalle en UD2 (cuando uses clases del API) y UD4 (cuando escribas las tuyas). Por ahora basta con que sepas que existen y que IntelliJ te las autocompleta cuando escribes /** y pulsas Enter encima de una declaración.
Cuándo comentar y cuándo no
Una buena regla: el código bien escrito se explica a sí mismo; los comentarios deben explicar el por qué, no el qué. Si tienes que escribir // incrementa i en 1 encima de i++, el comentario sobra. Si escribes // se suma 1 porque el ID 0 está reservado para el sistema, ese comentario sí aporta valor.
| Tipo de comentario | Útil para | Evita |
|---|---|---|
| Explicar el qué | Casi nunca | // asigna 5 a x |
| Explicar el por qué | Decisiones de diseño, workarounds | — |
| Documentar API pública | Clases y métodos públicos (Javadoc) | Documentar lo obvio |
| Marcar TODOs | // TODO: refactorizar cuando esté UD4 |
Acumular decenas sin hacerlos |
3.7 Convenciones de nomenclatura: camelCase, PascalCase, UPPER_SNAKE_CASE
Java no te obliga por ley a llamar a los elementos de tu programa de una manera concreta, pero toda la industria sigue las convenciones de Oracle (heredadas de Sun). Respetarlas no es opcional en la práctica: si las sigues, tu código se lee como "Java de verdad"; si no, se lee como "código de alguien que viene de otro lenguaje y no se ha adaptado o que no sabe programar".
Los tres estilos
flowchart TD
N["Nomenclatura Java"] --> C["camelCase"]
N --> P["PascalCase"]
N --> U["UPPER_SNAKE_CASE"]
N --> PKG["todo.en.minusculas"]
C --> C1["Variables y métodos"]
C --> C2["edad, calcularNotaMedia, nombreCompleto"]
P --> P1["Clases, interfaces, records, enums"]
P --> P2["Alumno, CalculadoraNotas, ListaCompras"]
U --> U1["Constantes (final o static final)"]
U --> U2["MAX_INTENTOS, PI, IVA_GENERAL"]
PKG --> PKG1["Paquetes"]
PKG --> PKG2["jams.programacion.ud1"]
style N fill:#1565c0,color:#fff,stroke:#0d47a1
style C fill:#e8f5e9,stroke:#2e7d32,color:#000
style P fill:#fff3e0,stroke:#e65100,color:#000
style U fill:#ffebee,stroke:#c62828,color:#000
style PKG fill:#f3e5f5,stroke:#6a1b9a,color:#000
Diagrama 3.4 — Convenciones de nomenclatura en Java y cuándo usar cada una.
Tabla resumen
| Elemento | Estilo | Ejemplos | Notas |
|---|---|---|---|
| Variables | camelCase | edad, nombreCompleto, notaMedia |
Empieza en minúscula, cada palabra siguiente en mayúscula |
| Métodos | camelCase | calcular(), obtenerNotaMedia() |
Verbos en infinitivo |
| Clases | PascalCase | Alumno, CalculadoraNotas |
Sustantivos |
| Interfaces | PascalCase | Comparable, List |
A veces adjetivos (Runnable) |
| Records | PascalCase | Punto, Coordenada |
Como clases |
| Enums | PascalCase (tipo), UPPER_SNAKE (valores) | DiaSemana.LUNES |
Los valores en mayúsculas |
| Constantes | UPPER_SNAKE_CASE | MAX_INTENTOS, PI, IVA_GENERAL |
final o static final |
| Paquetes | todo.minusculas.sin.guiones | jams.programacion.ud1 |
Dominio invertido |
Por qué importa tanto
Analogía
Las convenciones de nomenclatura son como la forma de vestir en un contexto profesional. No hay ninguna ley que te obligue a ir con camisa a una entrevista, pero si vas en chándal, el entrevistador se hace una idea de ti antes de que abras la boca. Con el código pasa lo mismo: si tus clases se llaman alumno (minúscula) o ALUMNO (mayúsculas) o alumno_clase (snake case), cualquier programador Java experimentado pensará "no ha programado en Java de verdad". Si las llamas Alumno, encajas en la comunidad y tu código se lee natural.
Reglas adicionales
- Los nombres deben ser significativos:
edadsí,eno (salvo en bucles muy cortos comofor (int i = 0; ...)). - Evita abreviaturas oscuras:
calcularNotaMediasí,calcNMno. - Los nombres booleanos suelen ser preguntas:
esMayorEdad,tienePermiso,puedeConducir. - No uses
_como prefijo (_nombre) ni$salvo en código generado automáticamente.
3.8 Paquetes y la sentencia package
Qué es un paquete y por qué existe
Un paquete en Java es un namespace (espacio de nombres) que agrupa clases relacionadas. Cumple tres funciones: organiza el código en estructuras jerárquicas, evita colisiones entre clases con el mismo nombre y controla la visibilidad entre clases de distintos paquetes.
Analogía
Un paquete es como una carpeta en un archivador. Si todos los documentos estuvieran en una sola carpeta, encontrarías el caos: decenas de ficheros con nombres parecidos, sin saber cuál pertenece a qué proyecto. Los paquetes permiten organizar el código igual que organizas tus apuntes: una carpeta para jams/, dentro otra para programacion/, dentro otra para ud1/, y dentro los ficheros de cada ejercicio.
La sentencia package
La primera línea (no vacía, sin contar comentarios) de cualquier fichero .java que declare una clase debe indicar a qué paquete pertenece:
Esta sentencia es obligatoria en todo fichero que declare una clase explícita (con public class o class). La única excepción son las implicitly declared classes de Java 25, donde puedes omitirla y la clase queda en el "paquete por defecto" (sin nombre); pero esta práctica se desaconseja en proyectos reales porque impide importar la clase desde otros paquetes.
Correspondencia paquete ↔ directorio
Java exige una correspondencia exacta entre el nombre del paquete y la estructura de carpetas:
| Paquete declarado | Ruta del fichero |
|---|---|
jams.programacion.ud1 |
jams/programacion/ud1/Main.java |
es.instituto.dam |
es/instituto/dam/Alumno.java |
| (sin paquete, paquete por defecto) | cualquier carpeta |
En un proyecto Maven, las clases van dentro de src/main/java/, así que el fichero completo sería src/main/java/jams/programacion/ud1/App.java. IntelliJ crea esta estructura automáticamente cuando le indicas el paquete al crear la clase.
Convención de nomenclatura: dominio invertido
La convención universal en Java para nombrar paquetes es usar el dominio de internet invertido como prefijo, para garantizar unicidad global:
| Organización | Dominio | Paquete |
|---|---|---|
Proyecto personal midominio.com |
midominio.com |
com.midominio.proyecto |
IES (imaginemos instituto.es) |
instituto.es |
es.instituto.dam |
| Apache Software Foundation | apache.org |
org.apache.commons |
| Este ciclo | — | jams.programacion.ud1 (forma corta por simplicidad) |
Las partes del paquete van en minúsculas (nunca Jams.Programacion.UD1), sin guiones (usa el punto como separador) y sin palabras reservadas de Java (int, class, new... no pueden ser partes de paquete).
Cómo IntelliJ te ayuda
Cuando creas una clase nueva con Alt+Insert → Java Class en IntelliJ y le pones como nombre jams.programacion.ud1.Calculadora, IntelliJ:
- Crea automáticamente las carpetas
jams/programacion/ud1/si no existen. - Genera el fichero
Calculadora.javaen la ruta correcta. - Añade la sentencia
package jams.programacion.ud1;al inicio del fichero.
Pista
Si mueves un fichero a otro paquete arrastrándolo en el árbol de IntelliJ, este actualiza automáticamente la sentencia package del fichero movido. Si lo hicieras a mano con el explorador de archivos, tendrías que cambiar la sentencia package tú mismo o el código no compilaría.
3.9 La sentencia import
Qué es y para qué sirve
La sentencia import permite usar clases de otros paquetes sin tener que escribir su nombre completo (fully qualified name) cada vez. Sin import, para usar Scanner tendrías que escribir:
Con import, basta una vez al inicio del fichero:
Sintaxis
La sentencia import va siempre después de package y antes de la declaración de la clase. Hay dos formas:
Pista
IntelliJ usa por defecto import específico (mejor para saber de dónde viene cada clase y para no sobrecargar el binario). El import wildcard se ve sobre todo en código antiguo o en tutoriales; evítalo en proyectos nuevos porque dificulta saber qué clases se están usando realmente.
Import estático
Existe una variante, el import estático, que permite usar miembros estáticos (constantes y métodos) sin cualificar con el nombre de la clase:
Útil cuando usas mucho una constante o método estático (como PI en cálculos geométricos), pero puede reducir la legibilidad si se abusa. En este ciclo lo verás aplicado sobre todo en UD6 (colecciones con import static).
Lo que NO necesitas importar
Java importa automáticamente el paquete java.lang, así que las clases más básicas están siempre disponibles sin import:
| Clase | Paquete | ¿Import necesario? |
|---|---|---|
String |
java.lang.String |
No (automático) |
System |
java.lang.System |
No |
Math |
java.lang.Math |
No |
Integer, Double, Boolean |
java.lang.* |
No |
Scanner |
java.util.Scanner |
Sí |
List, ArrayList, Map |
java.util.* |
Sí |
LocalDate |
java.time.LocalDate |
Sí |
Cómo IntelliJ gestiona los imports
IntelliJ hace prácticamente todo el trabajo por ti:
- Añadir import automáticamente: cuando escribes
Scannery pulsasAlt+Enter, IntelliJ añadeimport java.util.Scanner;al inicio del fichero. - Optimizar imports: con
Ctrl+Alt+Oelimina los imports que no se usan y ordena los restantes. - Auto-import al pegar: si pegas código que usa clases no importadas, IntelliJ te pregunta si quieres añadirlas.
Cuidado
Si ves una clase subrayada en rojo en IntelliJ con el mensaje "Cannot resolve symbol", casi siempre es que falta el import. Pulsa Alt+Enter sobre la clase y IntelliJ te propone el import correcto. Es una de las soluciones más mágicas del IDE.
3.10 Errores típicos del primer programa y cómo leerlos
Vamos a cerrar la sección con lo que más vas a ver en tus primeras semanas: mensajes de error del compilador. No te asustes: son tus amigos, no tus enemigos. Java tiene uno de los compiladores con mejores mensajes de error del mundo, y aprender a leerlos es una habilidad que te ahorrará horas.
Los cinco errores del 99% de los principiantes
| Error | Mensaje típico | Causa | Solución |
|---|---|---|---|
| Falta punto y coma | error: ';' expected |
Te dejaste un ; al final de una instrucción |
Añádelo en la línea que indica el error |
| Llave sin cerrar | error: reached end of file while parsing |
Falta un } en algún sitio |
Cuenta { y }; IntelliJ los resalta emparejados |
| Mayúscula incorrecta | error: cannot find symbol: variable Edad |
Usaste Edad pero declaraste edad |
Revisa mayúsculas/minúsculas |
| Clase vs fichero | error: class HolaMundo is public, should be declared in a file named HolaMundo.java |
Declaraste public class HolaMundo en un fichero con otro nombre |
Renombra el fichero o la clase para que coincidan |
| String sin cerrar | error: unclosed string literal |
Abriste comillas " y no las cerraste |
Cierra las comillas en la misma línea |
Cómo leer un mensaje de error
Un error del compilador tiene normalmente tres partes: el fichero, la línea y la descripción. Por ejemplo:
Léelo así:
- Fichero:
Main.java— dónde está el problema. - Línea 5 — en qué línea (ojo: a veces el error está en la línea anterior y se detecta al llegar a esta).
- Descripción:
';' expected— qué esperaba el compilador. - El cursor
^— dónde exactamente dentro de la línea.
Pista
Cuando IntelliJ subraya en rojo una línea, sitúa el cursor encima y aparecerá un tooltip con la explicación. Si pulsas Alt+Enter sobre el error, IntelliJ te propone la solución (añadir el ;, importar la clase, cambiar el nombre...). Es lo más parecido a magia que vas a encontrar en programación.
Errores de compilación vs errores de ejecución
Distinción importante que verás a lo largo del curso:
- Errores de compilación (compile-time): los detecta
javacantes de ejecutar. Falta de punto y coma, llaves, tipos incorrectos, variables no declaradas... El programa ni llega a ejecutarse. - Errores de ejecución (runtime): el programa compila bien pero falla al ejecutarse. Dividir por cero, acceder a un índice fuera de rango, llamar a un método sobre
null... Producen una excepción que verás en consola con un stack trace.
Este ArithmeticException es un error de ejecución: el programa compiló, pero al intentar dividir por cero la JVM detuvo la ejecución. El stack trace te dice exactamente qué pasó y en qué línea (Main.java:7). En UD3 aprenderás a manejar excepciones con try-catch; por ahora, basta con que sepas leer el mensaje.
Resumen de la sección 3
Antes de pasar a la siguiente sección, asegúrate de que controlas estos puntos:
- En Java 25 puedes escribir
void main() { ... }sinpublic classnistaticgracias a las implicitly declared classes y los instance main methods estables (JEP 512: Compact Source Files and Instance Main Methods). La forma clásicapublic static void main(String[] args)sigue siendo válida y necesaria en código pre-Java 25 y en proyectos con Maven. - Un programa Java clásico se compone de clase → método
main→ instrucciones. La clase es el contenedor obligatorio (aunque implícito en Java 25);maines la puerta de entrada que busca la JVM. - Para imprimir por consola tienes tres opciones:
println(con salto de línea),print(sin salto) yprintf(con formato).printfusa especificadores como%s,%d,%.2f,%n. - Java es sensible a mayúsculas, exige punto y coma al final de cada instrucción y delimita bloques con llaves
{ }equilibradas. - Hay tres tipos de comentarios:
//(línea),/* */(bloque) y/** */(Javadoc, que genera documentación HTML conjavadoc). Comenta el por qué, no el qué. - Las convenciones de nomenclatura de Oracle son: camelCase para variables y métodos, PascalCase para clases, UPPER_SNAKE_CASE para constantes, todo.minusculas para paquetes. Respetarlas es obligatorio en la práctica profesional.
- Los errores del compilador tienen fichero, línea y descripción. Aprende a leerlos y usa
Alt+Enteren IntelliJ para que te proponga soluciones automáticamente.