Photo by Mike Kenneally on Unsplash

Java-bashing is a popular past-time and I’m no exception, yet Java is the top programming language at the moment by many measures. Regardless of whether one thinks that Java is now growing, stagnating, or dying, one has to admit that Java had truly revolutionized and had defined the programming of XXI Century as we know it. Java had combined and brought to the masses tons of useful programming language features that were previously available only separately or in various niche languages.


However, Java had gained a strong foothold in desktop application development and became the language of choice for enterprise backend development.

Managed memory and desktop

Java’s strongest competitors for desktop development at the time were C++ and Delphi, yet Java was the only language in the game with memory safety and automatic garbage collection. This proved to be crucial for developer productivity, especially for the event-based style of UI that was prevalent at the time. Java programs were less error-prone to write in large teams. All kinds of reference and array-related failures in Java programs were universally easier to identify and to troubleshoot. These safety features of Java are not free in terms of CPU and memory consumption, yet it is not a show-stopper, but a gift for big desktop applications.

Cross-platform with advanced JIT

Bytecode was a common practice that programming languages employed back then, though often to the big detriment to performance. However, Java’s execution had quickly progressed from bytecode interpretation to advanced just-in-time compilation, to the point where performance of wide classes of algorithms had become competitive with state-of-the art C++ optimizers. This had defined the truly universal nature of Java. Over time most of the core algorithms in Java runtime library, that were written in C/C++ in its 1.0 version, were rewritten in Java itself, without losing (and often gaining) in performance.

Profile-guided optimization in the C/C++ world is still cumbersome to use, yet in the Java world, with the introduction of HotSpot around the turn of the century, it essentially became available for the masses in a hassle-free way, only for the cost of an additional startup time.

Application servers and dynamic loading

Java’s foothold on backend, surprisingly for modern observer, was also a function of its cross-platform offering. Linux was not a dominant backend operating system and x86 was not a dominant processor architecture back then. There was quite a variety, especially in the business world. The was no REST and even SOAP was just introduced. There was CORBA before SOAP, but it was just as heavy and it did not become as pervasive as REST/JSON now. So, whenever you had to integrate with somebody else’s API it usually meant using proprietary 3rd party code.

Finding binaries that you can use on your system was always quite a hassle in the C/C++ world. Even if you could convince your business partners to compile them for your target, any bugs there would irrevocably crash your code. Java’s business integration story was so much more compelling.

IDEs and refactoring

Around the turn of the Century, Martin Fowler published the Refactoring book on improving the design of existing code. It added a new word to the software developer’s vocabulary. IDEs had caught up and implemented fully automated refactoring support, ultimately revolutionizing the way software was written to begin with. It used to be the case that you had to think through the details and the structure of your code in excruciating detail in advance, since a failure to foresee the need to extract a certain piece of logic into a function or a class, badly chosen name or some other abstraction failure, would lead to costly, monotonous and utterly non-fun rework later on. Not any more. With IDE-supported refactoring you start writing your code in top-down fashion, introducing abstractions and renaming them as you discover the need for them. I’d say that this was one of the greatest improvements in software developer productivity of the XXI Century.

Java was uniquely positioned to reap the most benefits of automated refactoring by a pure chance. The original Java language design did not include any kind of macro system nor preprocessor because of the desire for simplicity and cross-platformness. These decisions turned out to be gold and made Java language exceedingly well suited to safe and automated refactoring in IDE.

The sum is greater than the parts

Bottom line

One can recognize the lessons that Java taught us in virtually every language and ecosystem that is now vying for the top in the modern world. Take today’s JavaScript-based web-applications and their Electron-based kin, for example. You’d see almost all the same ingredients that drove Java adoption on the desktop around the Millennium. Long live Java!

Project Lead for the Kotlin Programming Language @JetBrains

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store