Public static void main(String[] args) ha muerto
(mccue.dev)- 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
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?
Wow
¿Tengo que aprender Java otra vez..?
El
mainha muerto. ¡Larga vida almain!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
voidoString[]. Después aprendí sobre tipos y ya tuvo sentido, luego entendí los conceptos de class y object, y por quémainexistía como métodostatic. 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 liberadorSí, 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
Me pasó algo parecido. Como usé Java hace mucho tiempo, el patrón
public static void mainme resultaba familiar, pero la forma de usarScannerme 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
mainno afecta en absoluto mi día a día ni mi carrera. Me pregunto cuánto impacto real creen que tenga este cambioSi eres desarrollador Android, el concepto mismo de
mainno existía. Sinceramente, no creo que lo feo que sea la implementación de unHello Worldtrivial sea una buena medida de qué tan bien maneja el lenguaje cosas más complejasMucha gente empezó a programar con Java y escribió
maindecenas de veces sin tener idea de qué significabaPara 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, Worldfuncionaba como una barrera de entrada para los estudiantesSi 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
mainen ningún codebase. Y casi nunca creo clases nuevas directamente; normalmente solo implemento o extiendo clases específicas de algún frameworkJEP 445: Unnamed Classes and Instance Main Methods se lanzó en Java 21
https://openjdk.org/jeps/445
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 consistenteLa 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 importllegó 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 REPLEnlace relacionado
Hello Worldes 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 grandeSi 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 elreturn 0por defectoSi solo se permite
maincomo función top-level y nada más, entonces tampoco me parece un cambio especialmente buenoNo 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 importsNormalmente el IDE gestiona los
importautomá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 cualLa mayoría de los IDE para Java gestionan los
importautomáticamenteSi 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 partepublic class X { }y usarla solo cuando hiciera falta. No termino de entender por qué había que introducir clases sin nombreEl 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 fuentehttps://openjdk.org/jeps/445