17 puntos por GN⁺ 2025-09-18 | 5 comentarios | Compartir por WhatsApp
  • Ahora, el primer programa en Java ya no necesita empezar con public static void main(String[] args), y puede escribirse con la sintaxis simplificada void main()
  • Con la nueva sintaxis, la entrada y salida pueden manejarse con llamadas simples como IO.readln y IO.println, lo que hace que el código sea mucho más intuitivo
  • Las construcciones verbosas de antes, como new Scanner(System.in) y System.out.println, dejan de ser necesarias
  • Lo incómodo de todo este tiempo “por fin termina”; ahora que la estructura básica de Java se aligera, baja la barrera de entrada y mejora mucho la facilidad de aprendizaje

  • Tradicionalmente, Java exigía la larga declaración public static void main(String[] args) para iniciar un programa
  • Pero, al 16 de septiembre de 2025, la compleja declaración de la función main, considerada durante mucho tiempo el primer ejemplo de Java, fue reemplazada por una nueva forma simplificada
  • Forma anterior:
    public class Main {  
        public static void main(String[] args) {  
            Scanner scanner = new Scanner(System.in);  
            System.out.print("What is your name? ");  
            String name = scanner.nextLine();  
            System.out.println("Hello, " + name);  
        }  
    }  
    
  • Nueva forma:
    void main() {  
        var name = IO.readln("What is your name? ");  
        IO.println("Hello, " + name);  
    }  
    
  • Desde hace tiempo se criticaba por ser una sintaxis innecesariamente verbosa para principiantes y algo que había que memorizar como si fuera una “fórmula mágica”
  • Al resolver lo engorroso y lo difícil de entender de la declaración anterior, e introducir una sintaxis más concisa, mejora la legibilidad del código y baja de forma importante la barrera de entrada para aprender Java
    • Ya no se usan Scanner, System.out.println y otras creaciones de objetos y llamadas complejas como ejemplo básico

Good Fucking Riddance = “Por fin desapareció y qué alivio. Adiós y no vuelvas”

5 comentarios

 
kayws426 2025-09-22

Parece como si estuvieran diciendo que, solo porque apareció una nueva alternativa, el método existente ya murió.
¿De verdad ya no se puede usar el método anterior y ahora necesariamente hay que usar el nuevo?

 
jhk0530 2025-09-19

Wow

 
jwh926 2025-09-18

¿Tengo que aprender Java otra vez..?

 
carnoxen 2025-09-18

El main ha muerto. ¡Larga vida al main!

 
GN⁺ 2025-09-18
Comentarios en Hacker News
  • Creo que voy a extrañar ese proceso de ir entendiendo poco a poco este tipo de código que al principio se sentía tan ajeno. Cuando aprendí Python primero y luego pasé a Java, me llamaba la atención no entender qué significaban tipos como void o String[]. Después aprendí sobre tipos y ya tuvo sentido, luego entendí los conceptos de class y object, y por qué main existía como método static. Al profundizar más, también aprendí cuándo se invoca esta clase, y ese código que al principio parecía puro boilerplate empezó a tener sentido. Probablemente un desarrollador Java con más experiencia pueda leer todavía más significado en una sola línea que yo. Aun así, ahora que desaparece, se siente bastante liberador

    • Sí, se siente muy liberador. Durante los últimos 30 años, la educación en software les ha enseñado a los desarrolladores a producir complejidad innecesaria en nombre de la “ingeniería”. Por ejemplo, el desarrollador A crea una clase para lo que sea necesario: un entry point, un callback, una interfaz, etc. Como resultado, ya tenemos una clase. El desarrollador B añade variables de instancia a la clase y vuelve todo mutable, formando así un “lodo de implementación”. Después otro desarrollador agrega herencia para reutilizar código, pero eso trae todavía más complejidad y pesadillas de dispatch dinámico. Al final aparecen reference cycles y las relaciones entre objetos se enredan. Con el paso del tiempo, refactorizar se vuelve cada vez más difícil y tedioso, así que al final terminas borrando el código y empezando desde cero

    • Recuerdo que cuando empecé a aprender programación en la universidad, vi este código y el profesor dijo: “Normalmente les explicaría todo el código, pero esta parte por ahora solo acéptenla”. Más adelante, cuando miré atrás y me di cuenta de que ya entendía completamente ese código, fue una experiencia bastante genial. Aun así, parece que los tiempos están cambiando, así que también da alivio

    • En realidad, los métodos estáticos de clase son casi una negación de la realidad de que el único entry point de un programa tenga que estar necesariamente relacionado con una clase. Existen lenguajes como C++, y también Python o Ruby, que reconocen la realidad procedural, pero Java parece más bien querer vendarle los ojos al usuario y empujarlo hacia un “mundo OOP perfecto” a la fuerza

    • Desde la perspectiva de alguien que conocía la forma antigua basada en class, el estilo nuevo (como unnamed classes en Java 21) me genera más preguntas. Me pregunto si realmente convirtieron a Java, que supuestamente era un lenguaje donde “todo es un objeto”, en un lenguaje procedural. También me pregunto qué pasa si necesitas argumentos de línea de comandos. Normalmente evito Java, así que no sé mucho, pero esta vez lo pregunto en serio porque sí me da curiosidad

  • En la época de Java 1.2, la entrada estándar se leía así. La clase Scanner todavía me resulta poco familiar

BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
String input = in.readLine();
  • Me pasó algo parecido. Como usé Java hace mucho tiempo, el patrón public static void main me resultaba familiar, pero la forma de usar Scanner me parecía rara y no entendía bien por qué

  • En mi experiencia, como he trabajado durante décadas en proyectos grandes, cómo esté escrita la función main no afecta en absoluto mi día a día ni mi carrera. Me pregunto cuánto impacto real creen que tenga este cambio

    • Si eres desarrollador Android, el concepto mismo de main no existía. Sinceramente, no creo que lo feo que sea la implementación de un Hello World trivial sea una buena medida de qué tan bien maneja el lenguaje cosas más complejas

    • Mucha gente empezó a programar con Java y escribió main decenas de veces sin tener idea de qué significaba

    • Para los desarrolladores en activo no cambia mucho, pero para los principiantes sí es importante. Antes enseñaba Java, y ese conjuro mágico que había que memorizar antes de poder imprimir Hello, World funcionaba como una barrera de entrada para los estudiantes

    • Si estuvieras haciendo una interfaz de línea de comandos podría tener impacto, pero no es tan común crear CLI en Java

    • En los últimos 5 años no he visto main en ningún codebase. Y casi nunca creo clases nuevas directamente; normalmente solo implemento o extiendo clases específicas de algún framework

  • JEP 445: Unnamed Classes and Instance Main Methods se lanzó en Java 21
    https://openjdk.org/jeps/445

    • Es una lástima que esta funcionalidad haya salido limitada a programas de un solo archivo. Si hubieran permitido métodos a nivel de paquete o poner varias clases/records en un archivo, Java habría mejorado aún más. Pero en cualquier caso, parece que no querían que impactara la “forma general de escribir código Java”
  • Sorprende ver que, después de 30 años, Java por fin está evolucionando hacia un lenguaje bastante decente

    • Yo escribí bastante código solo en Java y C++, sin frameworks, y en ese contexto había mucho menos boilerplate y todo era más simple. Donde de verdad sentí una mejora enorme fue hace unos 10 años, cuando añadieron lambdas. Después de eso, el volumen del código bajó y la experiencia se volvió muchísimo más agradable. Durante mucho tiempo Java fue exageradamente explícito y estaba lleno de repeticiones innecesarias que parecía que solo servían para revisar typos en cosas triviales. Esa era la sensación hasta que despegó Kotlin; después, con lambdas y clases anónimas, la experiencia de desarrollo mejoró mucho

    • Decir que Java era un lenguaje terrible es una exageración enorme

    • En cambio, yo creo que lenguajes como Python siguen siendo incómodos incluso después de 30 años

    • Supongo que o nunca has usado un lenguaje realmente malo, o tu estándar de “no es terrible” es altísimo

    • Aun así, Java sí destaca mucho por su excelente compatibilidad hacia atrás y su sistema de gestión de paquetes

  • Ya lo mencioné en otro comentario, pero como desarrollador Java, Python me parece más extraño; aun así no creo que la forma actual sea mala. Eso sí, si uno empieza a programar sin entender las bases de la abstracción, quizá no sea una buena opción para “introducción a la programación”. Cuando una herramienta se diseña orientada a objetivos o a paradigmas, a veces termina en niveles extremos de abstracción. Java fue diseñado con foco en OOP, por eso es natural pensar en bloques como interfaces. Los modificadores de acceso de métodos/clases también se distinguen claramente según para quién son (public, protected, default, private, etc.). Es decir, empezar con Java implica comenzar desde la exposición de una interface hacia el usuario (programador). Puede parecer raro, pero al menos es consistente

    • La sintaxis pesada no tiene relación directa con OOP. Ninguna definición de OOP anterior a la aparición de Java decía que “las funciones no pueden existir fuera de una clase”. Durante mucho tiempo Sun se negó al concepto de funciones standalone (static import llegó en Java 5, los closures en Java 8, y los compact source files/instance main apenas ahora), y como resultado todas las funciones siguen estando dentro de clases (por razones prácticas y de compatibilidad, no filosóficas). Intentaron aferrarse a la idea de que “todo es un objeto”, pero en la práctica también introdujeron valores primitivos, lo cual ya era una contradicción. No hay ningún beneficio práctico en obligar a que las funciones estén dentro de una clase. De hecho, habría sido mejor si se pudieran definir métodos sobre valores como enteros. Por cierto, en lenguajes de “OOP puro” como Smalltalk puedes definir funciones libremente fuera de clases y ejecutar código directamente en un REPL
      Enlace relacionado

    • Hello World es importante porque permite mostrar al mismo tiempo el boilerplate necesario para ejecutar un programa y el código real que produce la salida. Además, desde la perspectiva de la configuración de herramientas de build, una parte de eso no es tanto “boilerplate” sino procedimiento práctico/configuración del entorno. Si se explica bien desde el principio, no es un problema tan grande

  • Si el compilador hace un truco y genera una clase internamente, entonces esto no pasa de ser un cambio cosmético. Si no se permiten otras top-level functions, al final sigue siendo solo un caso especial, así que todavía se siente raro

    • C# soporta top level statements desde la versión 9.0, pero al final igual se transforman internamente en métodos estáticos. Las múltiples top level functions funcionan de forma parecida. Ejemplo real: C# decompiled example
      Ese tipo de trucos son en realidad ejemplos útiles de transformaciones de compilador (closures, async state machine, etc.). Este cambio sería algo de ese estilo

    • En C/C++ también se siente igual de raro que solo en main() se aplique el return 0 por defecto

    • Si solo se permite main como función top-level y nada más, entonces tampoco me parece un cambio especialmente bueno

  • No entiendo por qué en los ejemplos de código Java suelen omitir las líneas de import. Si quieren mostrar la complejidad del boilerplate, entonces deberían escribir también los imports

    • Normalmente el IDE gestiona los import automáticamente, así que no se piensa mucho en eso. Y si son clases relacionadas con IO, en ejemplos compactos ni siquiera hace falta importar nada por separado, así que ese código realmente funciona tal cual

    • La mayoría de los IDE para Java gestionan los import automáticamente

  • Si abstrajeran el entry point public static void main(String[] args) con un paradigma de top-level statements como en C#, parecería que podrían reducir boilerplate y hacer el código más conciso; me pregunto por qué no lo hicieron así

    • Recomiendo leer Paving the on-ramp

    • Si el entry point existe como una excepción especial, entonces ya se está reconociendo el límite de OOP. Si es así, quizá valdría más la pena diseñar con más decisión una alternativa nueva

  • Me gusta que con el enfoque de unnamed class sea más fácil implementar variables globales, que además permita hot reload y que la sintaxis sea más compacta. Por otro lado, como los archivos Java tienen la restricción de que su nombre debe coincidir con el public class, quizá habría bastado con volver opcional la parte public class X { } y usarla solo cuando hiciera falta. No termino de entender por qué había que introducir clases sin nombre
    El compilador igual lo transforma en una clase como HelloWorld.class, así que ese nombre no deja de ser un detalle de implementación y en realidad no puede usarse directamente en el código fuente
    https://openjdk.org/jeps/445