En la lección anterior escribiste HolaBiblioTech.java y lo ejecutaste, pero lo hiciste copiando una estructura sin entenderla. Esa sensación de "escribo un conjuro y funciona" es incómoda y, sobre todo, impide avanzar: cuando algo falle no sabrás dónde mirar. Esta lección disecciona un fichero Java palabra por palabra: qué es un paquete, para qué sirve un import, qué significa cada término de public static void main(String[] args), cómo se separan las sentencias, cómo se comenta el código, qué convenciones de nombres sigue la comunidad entera y, muy importante, cómo leer los mensajes del compilador para no quedarte bloqueado nunca.

Contenido

  1. Anatomía completa de un fichero Java
  2. La declaración de paquete
  3. Los imports
  4. La declaración de clase
  5. El método main, palabra por palabra
  6. Sentencias, bloques y punto y coma
  7. Comentarios: línea, bloque y Javadoc
  8. Convenciones de nomenclatura
  9. Indentación y estilo
  10. Paquetes y directorios en la práctica
  11. Argumentos de línea de comandos: args
  12. Errores de compilación típicos y cómo leerlos
  13. Errores Comunes y Consejos
  14. Ejercicios

  1. Anatomía completa de un fichero Java

Empecemos por el mapa. Este es un fichero Java completo con todas sus partes, tal como quedará el arranque de BiblioTech:

package com.nexussoftware.bibliotech;          // 1. Declaracion de paquete

import java.util.Scanner;                      // 2. Imports

/**
 * Punto de entrada de BiblioTech, el sistema de gestion
 * de la biblioteca tecnica interna de Nexus Software.
 */
public class BiblioTechApp {                   // 3. Declaracion de clase

    public static void main(String[] args) {   // 4. Metodo main

        System.out.println("BiblioTech v0.1");  // 5. Sentencias

    }                                          // fin del metodo main
}                                              // fin de la clase

El orden de estas partes no es opcional: si existe declaración de paquete, va la primera; después los imports; después la clase. Invertir el orden es un error de compilación.

flowchart TD
    A["package com.nexussoftware.bibliotech;<br/><i>opcional, pero como máximo una y siempre la primera</i>"] --> B["import java.util.Scanner;<br/><i>cero o más</i>"]
    B --> C["public class BiblioTechApp {<br/><i>una clase pública por fichero</i>"]
    C --> D["public static void main(String[] args) {<br/><i>punto de entrada</i>"]
    D --> E["sentencias;<br/><i>terminadas en punto y coma</i>"]

  1. La declaración de paquete

package com.nexussoftware.bibliotech;

Un paquete es un espacio de nombres: agrupa clases relacionadas y evita colisiones. Si dos librerías distintas definen una clase Libro, sin paquetes sería imposible usar ambas; con paquetes son com.nexussoftware.bibliotech.Libro y com.otraempresa.Libro, y no hay ambigüedad.

Reglas concretas:

  • Debe ser la primera sentencia de código del fichero (solo pueden precederla comentarios).
  • Solo puede haber una por fichero.
  • Se escribe enteramente en minúsculas, con puntos separando niveles.
  • Por convención se usa el dominio de la organización al revés: Nexus Software controlaría nexussoftware.com, así que sus paquetes empiezan por com.nexussoftware. Después se añade el nombre del proyecto: com.nexussoftware.bibliotech.

Si omites la declaración, la clase queda en el paquete por defecto (sin nombre). Funciona para pruebas rápidas, pero está desaconsejado en cualquier código real: las clases del paquete por defecto no pueden ser importadas desde otros paquetes, lo que bloquea el crecimiento del proyecto. Durante este módulo verás ambas formas; a partir del módulo 3, cuando BiblioTech tenga varias clases, usaremos siempre paquete explícito.

  1. Los imports

import java.util.Scanner;

Un import le dice al compilador dónde encontrar una clase que vas a usar, para que puedas escribir Scanner en lugar del nombre completo java.util.Scanner cada vez.

Es importante entender lo que no hace: un import no copia código ni aumenta el tamaño del programa ni lo ralentiza. Es puramente una comodidad de escritura. Estas dos versiones son equivalentes:

// Con import
import java.util.Scanner;
...
Scanner entrada = new Scanner(System.in);

// Sin import, usando el nombre totalmente cualificado
java.util.Scanner entrada = new java.util.Scanner(System.in);

Variantes:

Forma Significado
import java.util.Scanner; Importa una clase concreta. Es la forma recomendada.
import java.util.*; Importa todas las clases del paquete java.util (no de sus subpaquetes)
import static java.lang.Math.PI; Import estático: permite escribir PI en vez de Math.PI

¿Por qué nunca has necesitado importar String ni System? Porque el paquete java.lang se importa automáticamente en todos los ficheros Java. Contiene lo más básico: String, System, Math, Integer, Object, Exception. Todo lo demás hay que importarlo.

Los IDE gestionan los imports por ti (IntelliJ los añade al escribir el nombre de la clase; Ctrl+Alt+O limpia los que sobran), pero conviene saber qué está pasando.

  1. La declaración de clase

public class BiblioTechApp {
    ...
}

En Java, todo el código ejecutable vive dentro de una clase. No existen funciones sueltas a nivel de fichero como en Python o JavaScript. Aunque en este módulo la clase sea solo un contenedor para main, a partir del módulo 3 verás su verdadero propósito: agrupar datos y comportamiento.

Diseccionemos la línea:

  • public es un modificador de acceso: indica que la clase es visible desde cualquier otro paquete. La alternativa es no poner nada (visibilidad de paquete). Los modificadores de acceso se estudian a fondo en la lección 03-07.
  • class es la palabra reservada que declara una clase.
  • BiblioTechApp es el nombre. Debe empezar por letra, $ o _ (en la práctica, siempre por letra) y no puede ser una palabra reservada del lenguaje.
  • { ... } delimitan el cuerpo de la clase. Todo lo que pertenece a la clase va dentro.

La regla del nombre del fichero, ya adelantada: si la clase es public, el fichero debe llamarse exactamente igual que ella más .java. public class BiblioTechAppBiblioTechApp.java. Java distingue mayúsculas de minúsculas, así que bibliotechapp.java no vale. Un fichero puede contener varias clases, pero solo una de ellas puede ser public.

  1. El método main, palabra por palabra

public static void main(String[] args) {

Esta firma es un contrato con la JVM. Cuando ejecutas java BiblioTechApp, la máquina virtual busca en esa clase un método con exactamente esta forma. Si difiere en cualquier detalle, no arranca. Analicemos cada término:

Palabra Qué significa Por qué es necesaria aquí
public Accesible desde cualquier sitio La JVM llama al método desde fuera de tu clase; si fuera privado no podría
static Pertenece a la clase, no a un objeto Al arrancar el programa no existe todavía ningún objeto de BiblioTechApp; sin static la JVM tendría que crear uno primero
void No devuelve ningún valor Cuando main termina, no hay nadie en tu código a quien devolverle nada
main El nombre exacto que busca la JVM Es una convención fijada por la plataforma, no puede ser otro
String[] args Un parámetro: array de cadenas Recibe los argumentos escritos en la línea de comandos

Detalles que suelen sorprender:

  • El nombre del parámetro puede cambiar: String[] argumentos es igual de válido. Lo que no puede cambiar es su tipo.
  • String[] args y String args[] son equivalentes; la primera forma es la convención moderna.
  • Desde Java 21 se puede escribir void main() sin modificadores en ficheros de un solo fichero (una característica en previsualización pensada para el aprendizaje). Este curso usa la forma estándar completa, que es la que encontrarás en todo el código profesional.
  • Puedes escribir static public void main(...): el orden de los modificadores es libre. La convención es public static.

Si te equivocas en la firma, el programa compila sin problemas (es un método válido, simplemente no es el main), pero al ejecutar obtienes:

Error: Main method not found in class BiblioTechApp

Es decir, un error de ejecución, no de compilación. Recordarlo te ahorrará confusión.

  1. Sentencias, bloques y punto y coma

Una sentencia es una instrucción completa. En Java toda sentencia termina en punto y coma:

int anioPublicacion = 2018;
System.out.println("BiblioTech");
double multa = diasRetraso * 0.25;

Un bloque es un conjunto de sentencias entre llaves { }. Los bloques definen el cuerpo de clases y métodos, y más adelante el de condicionales y bucles.

La regla que evita el 90 % de las dudas: las llaves no llevan punto y coma detrás.

public class BiblioTechApp {   // sin ; despues de la llave
    public static void main(String[] args) {   // sin ; tampoco
        System.out.println("Hola");            // CON ; : es una sentencia
    }                                          // sin ;
}                                              // sin ;

Java es un lenguaje de formato libre: los saltos de línea y los espacios no cambian el significado, solo la legibilidad. Estas tres versiones compilan idénticamente:

// Legible
int anioPublicacion = 2018;
String titulo = "Java Efectivo";

// Igualmente valido, ilegible
int anioPublicacion=2018;String titulo="Java Efectivo";

// Igualmente valido, absurdo
int
    anioPublicacion
        =
            2018 ;

Que el compilador acepte las tres no significa que valgan lo mismo: el código se lee muchas más veces de las que se escribe.

  1. Comentarios: línea, bloque y Javadoc

Los comentarios son texto que el compilador ignora. Java tiene tres formas y cada una tiene su lugar:

// Comentario de una linea. Todo lo que sigue a // hasta el fin de linea se ignora.

/*
   Comentario de bloque.
   Puede ocupar varias lineas.
   Util para desactivar temporalmente un fragmento de codigo.
*/

/**
 * Comentario Javadoc. Se escribe ANTES de una clase, metodo o campo
 * y sirve para generar documentacion HTML con la herramienta javadoc.
 *
 * @author Equipo BiblioTech
 * @version 0.1
 */
Tipo Sintaxis Uso típico
Línea // texto Aclarar una línea concreta; el más habitual
Bloque /* texto */ Explicaciones largas; desactivar código temporalmente
Javadoc /** texto */ Documentar la API pública: qué hace una clase o método

Javadoc es más que un comentario bonito: la herramienta javadoc incluida en el JDK genera con ellos un sitio web de documentación, y los IDE los muestran como ayuda contextual cuando pasas el ratón sobre una clase. La documentación oficial de la API de Java está generada exactamente así. Sus etiquetas más usadas son @param (describe un parámetro), @return (describe el valor devuelto) y @author. En este módulo apenas las usarás porque solo tienes main, pero a partir del módulo 3 serán habituales.

Un consejo sobre el buen comentario: no expliques qué hace el código si el código ya lo dice; explica por qué.

// MAL: redundante, no aporta nada
int diasRetraso = 12;   // asigna 12 a diasRetraso

// BIEN: aporta contexto que el codigo no puede expresar
// Nexus Software concede 15 dias naturales de prestamo antes de aplicar multa.
final int DIAS_PRESTAMO = 15;

  1. Convenciones de nomenclatura

Java no obliga a seguirlas: el compilador acepta class biblio_tech_app. Pero la comunidad Java es excepcionalmente uniforme en este punto, y saltarse las convenciones marca inmediatamente el código como amateur. Además, tienen un valor funcional: te dicen de un vistazo qué tipo de elemento estás mirando.

Elemento Convención Ejemplos de BiblioTech
Clase e interfaz PascalCase (cada palabra en mayúscula) BiblioTechApp, Libro, GestorPrestamos
Método camelCase, empieza por verbo calcularMulta(), registrarPrestamo()
Variable camelCase titulo, anioPublicacion, diasRetraso
Constante MAYUSCULAS_CON_GUION_BAJO TARIFA_DIARIA, DIAS_PRESTAMO
Paquete todo.en.minusculas com.nexussoftware.bibliotech

Por qué importan de verdad:

  • Al leer Libro libro = ... sabes sin pensar que Libro es un tipo y libro una variable. La convención elimina la ambigüedad.
  • Al ver TARIFA_DIARIA sabes que es un valor que no cambia, sin ir a buscar su declaración.
  • Los IDE, los analizadores estáticos y las herramientas de generación de código las asumen.

Reglas adicionales sobre nombres:

  • Deben empezar por letra, _ o $. Nunca por dígito.
  • Pueden contener letras, dígitos, _ y $. Java admite acentos y ñ porque acepta Unicode, pero evítalos: causan problemas de codificación entre sistemas. Escribe anioPublicacion, no añoPublicación.
  • No pueden ser palabras reservadas (class, int, public, static, new, return…).
  • Se distinguen mayúsculas y minúsculas: titulo, Titulo y TITULO son tres identificadores diferentes.
  • Usa nombres descriptivos. diasRetraso es infinitamente mejor que d o x. El nombre de una variable es la documentación más leída del código.

  1. Indentación y estilo

La indentación no afecta a la compilación, pero es lo primero que separa el código legible del ilegible. Las convenciones dominantes en Java:

  • Cuatro espacios por nivel de anidamiento (no tabuladores; configúralo en tu IDE).
  • Llave de apertura al final de la línea, no en línea propia. Es el estilo oficial de Java y difiere del habitual en C#.
  • Un espacio alrededor de los operadores: int total = a + b;, no int total=a+b;.
  • Líneas de longitud razonable (100-120 caracteres como máximo).
  • Una línea en blanco para separar bloques lógicos.
// Estilo Java convencional
public class BiblioTechApp {

    public static void main(String[] args) {
        String titulo = "Java Efectivo";
        int anioPublicacion = 2018;

        System.out.println(titulo + " (" + anioPublicacion + ")");
    }
}

Todos los IDE reformatean automáticamente: en IntelliJ es Ctrl+Alt+L, en Eclipse Ctrl+Shift+F, en VS Code Shift+Alt+F. Acostúmbrate a pulsarlo antes de dar por terminado un fichero.

  1. Paquetes y directorios en la práctica

Aquí hay una regla estricta que provoca muchos errores al empezar: la jerarquía de paquetes debe corresponderse con la jerarquía de directorios.

Si tu fichero declara:

package com.nexussoftware.bibliotech;

entonces BiblioTechApp.java debe estar en .../com/nexussoftware/bibliotech/BiblioTechApp.java.

flowchart TD
    A["src/main/java/"] --> B["com/"]
    B --> C["nexussoftware/"]
    C --> D["bibliotech/"]
    D --> E["BiblioTechApp.java<br/>package com.nexussoftware.bibliotech;"]

Y esto cambia cómo compilas y ejecutas desde la terminal. Situado en src/main/java:

# Compilar indicando la ruta completa del fichero
javac com/nexussoftware/bibliotech/BiblioTechApp.java

# Ejecutar usando el nombre COMPLETAMENTE CUALIFICADO de la clase
java com.nexussoftware.bibliotech.BiblioTechApp

Observa la diferencia esencial: al compilar usas barras (es una ruta de fichero); al ejecutar usas puntos (es un nombre de clase). Escribir java BiblioTechApp a secas cuando la clase está en un paquete produce Could not find or load main class, porque el nombre real de la clase incluye su paquete.

Una opción práctica para no ensuciar el código fuente con los .class:

javac -d ../../../out com/nexussoftware/bibliotech/BiblioTechApp.java
java -cp ../../../out com.nexussoftware.bibliotech.BiblioTechApp
  • -d indica el directorio de salida de los .class, y javac recrea allí la estructura de paquetes automáticamente.
  • -cp (classpath) indica dónde debe buscar las clases el comando java.

Cuando trabajes en el IDE, todo esto lo gestiona él; pero cuando algo falle, sabrás qué está haciendo por debajo.

  1. Argumentos de línea de comandos: args

El parámetro String[] args recibe los valores que escribes después del nombre de la clase al ejecutar. Es la forma más simple de pasar datos a un programa.

public class ArgumentosBiblioTech {
    public static void main(String[] args) {
        // args.length indica cuantos argumentos se han recibido.
        System.out.println("Argumentos recibidos: " + args.length);

        // args[0] es el primero, args[1] el segundo... (se cuenta desde 0)
        System.out.println("Primer argumento: " + args[0]);
        System.out.println("Segundo argumento: " + args[1]);
    }
}

Ejecución:

javac ArgumentosBiblioTech.java
java ArgumentosBiblioTech "Java Efectivo" 978-0000000001

Salida:

Argumentos recibidos: 2
Primer argumento: Java Efectivo
Segundo argumento: 978-0000000001

Puntos clave:

  • Los argumentos se separan por espacios. Si un valor contiene espacios (como Java Efectivo), hay que rodearlo de comillas; si no, llegarían como dos argumentos distintos.
  • Siempre llegan como String, aunque escribas un número. java Programa 2018 hace que args[0] sea el texto "2018", no el número. Para convertirlo se usa Integer.parseInt(args[0]), que verás en la lección 01-04.
  • El índice empieza en 0: el primer argumento es args[0].
  • Si accedes a un índice que no existe (por ejemplo args[1] cuando solo has pasado uno), el programa falla en ejecución con ArrayIndexOutOfBoundsException. Comprobar args.length antes requiere condicionales, que llegan en el módulo 2; el tratamiento del error, en el módulo 6.
  • El nombre de la clase no forma parte de args, a diferencia de lo que ocurre en C.

En los IDE también se pueden configurar: en IntelliJ, Run → Edit Configurations… → Program arguments.

  1. Errores de compilación típicos y cómo leerlos

Aprender a leer los mensajes de javac es una habilidad que se paga sola. El formato es siempre el mismo:

Fichero.java:NUMERO_DE_LINEA: error: DESCRIPCION
        el codigo de esa linea
              ^   <- señala la posicion exacta
1 error

Veamos los cuatro más frecuentes con su diagnóstico.

';' expected

System.out.println("BiblioTech")   // falta el punto y coma
BiblioTechApp.java:4: error: ';' expected
        System.out.println("BiblioTech")
                                        ^

Diagnóstico: falta un punto y coma. Aviso importante: el compilador señala el final de la línea anterior al problema, así que si el error parece no tener sentido en la línea indicada, mira la línea de arriba.

cannot find symbol

System.out.println(titulo);   // 'titulo' no se ha declarado
BiblioTechApp.java:5: error: cannot find symbol
        System.out.println(titulo);
                           ^
  symbol:   variable titulo
  location: class BiblioTechApp

Diagnóstico: el compilador no conoce ese nombre. Las tres causas, por frecuencia: (1) no lo has declarado; (2) lo has escrito con mayúsculas distintas (Titulo vs titulo); (3) falta el import de una clase.

incompatible types

int anioPublicacion = "2018";   // texto asignado a un entero
BiblioTechApp.java:4: error: incompatible types: String cannot be converted to int
        int anioPublicacion = "2018";
                              ^

Diagnóstico: el tipado estático de Java en acción. Estás metiendo un valor de un tipo en una variable de otro. Es exactamente la clase de error que en un lenguaje dinámico explotaría en producción.

class X is public, should be declared in a file named X.java

Diagnóstico: el nombre del fichero no coincide con el de la clase pública. Renombra uno de los dos.

Errores de compilación frente a errores de ejecución

Es una distinción fundamental:

Error de compilación Error de ejecución
Cuándo aparece Al ejecutar javac, antes de correr nada Mientras el programa está funcionando
Quién lo detecta El compilador La JVM
Ejemplos Falta ;, tipos incompatibles, símbolo no encontrado ArrayIndexOutOfBoundsException, división entera por cero
Coste Barato: lo ves en segundos Caro: puede aparecer solo con ciertos datos, incluso en producción

Un consejo de método: cuando javac reporte veinte errores, corrige solo el primero y vuelve a compilar. Un único fallo (una llave sin cerrar, por ejemplo) desencadena una cascada de errores derivados que desaparecen solos.

Errores Comunes y Consejos

  • Poner punto y coma detrás de la llave de cierre de un método o clase. No es un error grave (Java lo tolera como sentencia vacía en algunos contextos), pero delata desconocimiento y en otros produce error.
  • Escribir Main en lugar de main. Java distingue mayúsculas: compila, pero al ejecutar dice Main method not found.
  • Olvidar que la clase pública y el fichero deben llamarse igual.
  • Colocar el import antes del package. El orden es fijo: package, luego import, luego la clase.
  • Ejecutar java BiblioTechApp cuando la clase está en un paquete. Hay que usar el nombre cualificado completo: java com.nexussoftware.bibliotech.BiblioTechApp.
  • Fiarse del número de línea del error sin mirar la anterior. Muy típico con ';' expected.
  • Consejo: configura tu IDE para que formatee al guardar. Nunca discutirás sobre estilo y tu código será uniforme desde el primer día.
  • Consejo: cuando copies código de internet, tecléalo. Los errores que cometas y corrijas son el aprendizaje real.
  • Consejo: las llaves desbalanceadas son la causa más frecuente de errores incomprensibles. Todos los IDE resaltan la llave pareja al situar el cursor sobre una: úsalo.

Ejercicios

Ejercicio 1: Cazar los errores

El siguiente fichero, guardado como BiblioTechApp.java, contiene cinco errores. Localízalos, explica por qué son errores y escribe la versión corregida.

import java.util.Scanner;
package com.nexussoftware.bibliotech;

public class bibliotechApp {
    public static void Main(String args) {
        System.out.println("BiblioTech - Nexus Software")
        System.out.println("Libro: " + Titulo);
    }
}

Ejercicio 2: Ficha con paquete y argumentos

Crea la clase FichaBiblioTech dentro del paquete com.nexussoftware.bibliotech, con la estructura de directorios correcta. El programa debe recibir por línea de comandos el título y el ISBN de un libro y mostrarlos junto a una cabecera. Incluye un comentario Javadoc en la clase y un comentario de línea que explique de dónde salen los datos. Escribe también los comandos exactos de compilación y ejecución.

Ejecución esperada:

java com.nexussoftware.bibliotech.FichaBiblioTech "Patrones de Diseno" 978-0000000002

Salida:

=== BiblioTech (Nexus Software) ===
Titulo: Patrones de Diseno
ISBN: 978-0000000002

Ejercicio 3: Aplicar las convenciones

El siguiente código compila perfectamente, pero incumple todas las convenciones de Java. Reescríbelo aplicándolas y justifica cada cambio.

public class prestamo_app{
public static void main(String[] args){
int DiasRetraso=12;
double tarifa_diaria=0.25;
final double multa_maxima=20.0;
String Nombre_Empleado="Marta Ruiz";
System.out.println(Nombre_Empleado+" debe "+(DiasRetraso*tarifa_diaria));
}
}

Soluciones

Solución 1

Los cinco errores:

  1. import antes de package. La declaración de paquete debe ser la primera sentencia del fichero.
  2. class bibliotechApp no coincide con el nombre del fichero BiblioTechApp.java. Además incumple PascalCase.
  3. Main en lugar de main. Con mayúscula no es el punto de entrada; el programa compilaría pero fallaría al ejecutarse con Main method not found.
  4. String args en lugar de String[] args. El parámetro debe ser un array de cadenas; sin los corchetes, la firma no es la que busca la JVM.
  5. Falta el punto y coma al final del primer println. Y hay un sexto problema encadenado: Titulo no está declarado en ninguna parte, lo que produciría cannot find symbol.

Versión corregida:

package com.nexussoftware.bibliotech;   // 1. El package va SIEMPRE el primero

import java.util.Scanner;               // El import va despues del package

// 2. El nombre de la clase publica coincide con el del fichero, en PascalCase
public class BiblioTechApp {

    // 3 y 4. Firma exacta que busca la JVM: main en minusculas y String[]
    public static void main(String[] args) {

        // Declaramos la variable antes de usarla (soluciona 'cannot find symbol')
        String titulo = "Java Efectivo";

        // 5. Toda sentencia acaba en punto y coma
        System.out.println("BiblioTech - Nexus Software");
        System.out.println("Libro: " + titulo);
    }
}

Nota: si finalmente no usas Scanner, lo correcto es eliminar su import. Un import sin usar no es un error, pero sí ruido.

Solución 2

Estructura de directorios, partiendo de la raíz del proyecto:

bibliotech/
└── src/
    └── main/
        └── java/
            └── com/
                └── nexussoftware/
                    └── bibliotech/
                        └── FichaBiblioTech.java

El fichero:

package com.nexussoftware.bibliotech;

/**
 * Muestra por consola la ficha basica de un libro del catalogo de BiblioTech.
 * Los datos se reciben como argumentos de linea de comandos.
 *
 * @author Equipo BiblioTech - Nexus Software
 * @version 0.1
 */
public class FichaBiblioTech {

    public static void main(String[] args) {
        // args[0] y args[1] llegan desde la linea de comandos, en ese orden,
        // y SIEMPRE son de tipo String aunque contengan digitos.
        String titulo = args[0];
        String isbn = args[1];

        System.out.println("=== BiblioTech (Nexus Software) ===");
        System.out.println("Titulo: " + titulo);
        System.out.println("ISBN: " + isbn);
    }
}

Comandos, situándose en src/main/java:

# Compilar: se indica la RUTA del fichero, con barras
javac -d ../../../out com/nexussoftware/bibliotech/FichaBiblioTech.java

# Ejecutar: se indica el NOMBRE DE LA CLASE cualificado, con puntos
java -cp ../../../out com.nexussoftware.bibliotech.FichaBiblioTech "Patrones de Diseno" 978-0000000002

Detalle importante: "Patrones de Diseno" va entre comillas porque contiene un espacio. Sin ellas, el sistema pasaría tres argumentos (Patrones, de, Diseno) y la salida sería incorrecta.

Solución 3

/**
 * Calcula la multa por retraso de un prestamo de BiblioTech.
 */
public class PrestamoApp {                         // PascalCase, no snake_case

    public static void main(String[] args) {
        int diasRetraso = 12;                      // camelCase para variables
        double tarifaDiaria = 0.25;                // camelCase, no snake_case
        final double MULTA_MAXIMA = 20.0;          // constante: MAYUSCULAS_CON_GUION
        String nombreEmpleado = "Marta Ruiz";      // camelCase, empieza en minuscula

        double multa = diasRetraso * tarifaDiaria; // extraemos el calculo a una variable

        System.out.println(nombreEmpleado + " debe " + multa + " euros");
        System.out.println("Multa maxima aplicable: " + MULTA_MAXIMA + " euros");
    }
}

Justificación de cada cambio:

Antes Después Motivo
prestamo_app PrestamoApp Las clases usan PascalCase; snake_case no es estilo Java
DiasRetraso diasRetraso Empezar por mayúscula hace que parezca una clase
tarifa_diaria tarifaDiaria Las variables usan camelCase
multa_maxima MULTA_MAXIMA Es final, es decir, una constante: se escribe en mayúsculas
Nombre_Empleado nombreEmpleado Mezclaba dos convenciones incorrectas a la vez
Sin indentación 4 espacios por nivel Legibilidad
Cálculo dentro del println Variable multa Separa el cálculo de la presentación y facilita reutilizarlo

Conclusión

Ya no hay conjuros: sabes que un fichero Java se ordena en package, import y clase; que public static void main(String[] args) es un contrato con la JVM y qué aporta cada palabra; que las sentencias terminan en punto y coma y las llaves no; que hay tres tipos de comentario y que Javadoc genera documentación real; que las convenciones de nombres comunican información de un vistazo; que los paquetes se corresponden con directorios y eso cambia cómo compilas y ejecutas; que args trae argumentos de la línea de comandos siempre como texto; y, sobre todo, cómo leer un mensaje de error del compilador en lugar de bloquearte ante él.

En la siguiente lección, Variables y Tipos de Datos, llenaremos de contenido ese esqueleto: los ocho tipos primitivos con sus rangos, los literales, la diferencia entre tipos primitivos y por referencia, String y su inmutabilidad, las conversiones de tipo, las constantes con final y la inferencia con var. Al terminarla podrás modelar un libro completo del catálogo de BiblioTech con variables.

Curso de Programación en Java

Módulo 1: Introducción a Java

Módulo 2: Flujo de Control

Módulo 3: Programación Orientada a Objetos

Módulo 4: Programación Orientada a Objetos Avanzada

Módulo 5: Estructuras de Datos y Colecciones

Módulo 6: Manejo de Excepciones

Módulo 7: Entrada/Salida de Archivos

Módulo 8: Multihilo y Concurrencia

Módulo 9: Redes

Módulo 10: Temas Avanzados

Módulo 11: Frameworks y Librerías de Java

Módulo 12: Construcción de Aplicaciones del Mundo Real

© Copyright 2026. Todos los derechos reservados