Java Was Optimized for LLMs Decades Before They Existed 📎
Java specifications, JSRs and JavaDoc have been public, versioned and consistently formatted for three decades. Jakarta EE and MicroProfile publish theirs as plain HTML on the open web, where Common Crawl picks them up, and Common Crawl is one of the most widely used sources of LLM training data. Most major model providers do not publish their complete corpora, so nobody can prove a specific spec sits inside a specific proprietary model. Public HTML in these quantities is exactly what those corpora are built from. Beyond the amount of text, the language itself happens to be built the way an LLM likes it.
- Explicit types. The contract is written down, not inferred by the reader. A generated signature carries its own meaning, and a wrong guess is rejected by the compiler.
- Verbosity. Redundant syntax works as error correction. The same intent shows up in the type, the name and the annotation, so a single mistaken token rarely survives.
- Rigid conventions.
PascalCasetypes,camelCasemethods, reverse domain packages, one public type per file. Highly predictable, low entropy. - Annotations.
@Path,@Injectand@GETdeclare a concern instead of implementing it. The names are standardized and appear identically across the whole ecosystem, so the model recognizes what is being asked for, and the container supplies the registration, the lookup and the lifecycle. Intent without wiring. - Backwards compatibility. Java takes source and binary compatibility seriously, and modern tooling still reads class files from compilers that went out of use decades ago. Books, articles and answers from years back describe code that largely still works, so old material stays useful instead of turning into noise.
- Normative prose. Jakarta specs state requirements as MUST, SHOULD and MAY, usually citing RFC 2119. MicroProfile defines the required behavior and ships a TCK that checks it. The JLS repeats "it is a compile-time error if" throughout. Precise prose, and something executable that verifies it.
- Implementation independence.
@Injectis JSR 330, not the property of any container. It is read by Jakarta EE, Quarkus, Micronaut, Helidon, Spring, WildFly, JBoss EAP, Payara, GlassFish, Open Liberty, WebLogic, Vidocq, Google Guice, Dagger, Eclipse Sisu, Apache Maven and the Eclipse Platform, and CDI adds scopes, qualifiers, producers and events on top of it. Ecosystems that agree on almost nothing else agree on this one, so the model writes a token with stable meaning instead of picking between unrelated vendor injection APIs. Fewer places to go wrong. - A fast compiler as verifier. Invented method names never reach production, they fail in the build.
javacneeds seconds, andjava App.javaruns a source file without any build step. Generate, compile, correct is cheap enough to become the model's inner loop.
The result is code with very few degrees of freedom:
public class Garage {
@Inject
Cars cars;
@Inject
Event<CarRegistered> registered;
public void register(Car car) {
this.cars.add(car);
this.registered.fire(CarRegistered.of(car.id()));
}
}
The standardized APIs fix the programming model, javac checks the types and signatures, and the container checks the injection points and the wiring. The model fills in a predefined programming model instead of inventing one.