☕ Java — 1995

⬅️ Atlas · 🗂️ Todas las fichas · 📚 Índice de clases

Java es el lenguaje que llevó la máquina virtual y la recolección de basura al software empresarial del mundo entero. Treinta años después sigue moviendo los sistemas de banca, seguros y comercio de media Europa — y, después de una década de fama de lento y verboso, ha cambiado más en los últimos seis años que en los veinte anteriores.

🎯 Por qué está en este programa

Java es uno de los diez lenguajes del núcleo y el representante de la familia JVM (Atlas): quien entiende la versión Java de una clase reconoce después Kotlin, Scala, Groovy y —con más esfuerzo— Clojure, porque los cuatro compilan al mismo bytecode y comparten biblioteca.

Y aporta al programa los conceptos de máquina virtual con JIT (clases 125 y 126), recolección de basura generacional (clase 131) y orientación a objetos nominal con interfaces (clase 112), que son los que definieron la práctica de la industria durante veinte años.

Año 1995; 5 con genéricos (2004); 8 con lambdas (2014); cada 6 meses desde 2017
Autoría James Gosling y equipo, Sun Microsystems (hoy Oracle)
Familia JVM; sintaxis de C, semántica influida por Smalltalk y Objective-C
Paradigma Orientado a objetos con clases; funcional desde Java 8
Tipado Estático, nominal y fuerte; con genéricos por borrado
Memoria Recolección de basura; varios recolectores intercambiables
Ejecución Bytecode sobre la JVM, con JIT de dos niveles; también AOT con GraalVM
Estado 🟢 Dominante en sistemas empresariales y en el ecosistema de datos

📜 Historia

En 1991, Sun montó el proyecto Green para hacer software de electrodomésticos: un mando a distancia inteligente. James Gosling diseñó un lenguaje llamado Oak —por un roble que veía desde su ventana— con dos requisitos que resultaron proféticos: portabilidad entre chips distintos y seguridad, porque el código iba a viajar.

El mercado de la televisión interactiva no llegó, pero en 1995 llegó la web, y Sun reposicionó el lenguaje como Java, con el eslogan "write once, run anywhere" y los applets en el navegador. Los applets murieron; la máquina virtual sobrevivió y ganó.

Los hitos que lo formaron:

Y por el camino, el juicio Oracle contra Google sobre las APIs de Java —resuelto en 2021 a favor del uso legítimo— definió jurisprudencia sobre si una interfaz de programación se puede copiar.

🏭 Dónde vive hoy

🧠 Lo que enseña: la máquina virtual como decisión de arquitectura

Java es el sitio donde mejor se ve el compromiso central de las clases 125 y 126:

Compilar a bytecode y ejecutarlo en una máquina virtual con JIT da:
  + portabilidad real entre sistemas y arquitecturas
  + optimización con información de EJECUCIÓN, que un compilador estático no tiene
  + recolección de basura, seguridad de memoria y verificación del bytecode
  − arranque más lento y consumo de memoria mayor
  − y pausas del recolector, que en latencia baja importan (clase 152)

El JIT con información de ejecución merece el detalle, porque es contraintuitivo: la JVM puede generar código más rápido que un compilador estático en ciertos casos, porque sabe qué rama se toma siempre y qué tipo llega de verdad a un método polimórfico, y compila especializando —con una comprobación de guarda por si cambia—.

Es exactamente la caché de envío en línea que se inventó en Smalltalk y en Self (clase 152), y es la razón por la que el despacho dinámico dejó de ser caro.

Y el otro concepto que Java llevó a la industria es el de la clase 112: la interfaz como contrato sin implementación, con herencia simple de clases y múltiple de interfaces — la respuesta al problema del diamante que C++ tiene abierto.

🔄 Lo que se ha modernizado

⚙️ Cómo se ejecuta hoy

javac Main.java && java Main < entrada.txt     # el camino de la clase 041
java Main.java                                  # desde Java 11: sin compilar antes

mvn verify        # o: gradle build             (clase 143)
java -jar app.jar
native-image -jar app.jar                        # GraalVM: binario nativo (clase 174)

🧪 El programa de la clase 041 en Java

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Locale;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String[] p = br.readLine().trim().split("\\s+");

        // Tipado estático nominal: cada valor declara su tipo.
        final double precioUnitario = Double.parseDouble(p[0]);
        final int cantidad = Integer.parseInt(p[1]);
        final double descuento = Double.parseDouble(p[2]);

        double subtotal = precioUnitario * cantidad;
        double total = subtotal * (1 - descuento);

        System.out.printf(Locale.US, "Total: %.2f%n", total);
    }
}

Lo que hay que ver, comparando con las otras fichas.

📚 Fuentes y bibliografía


⏮️ Volver al Atlas · 🗂️ Todas las fichas · 🔗 Relacionadas: Kotlin · Scala · Groovy · Clojure · C# · Smalltalk