I recently started learning Java as my first language for building substantial projects. Before that I tried Python, but found it too abstract and not very engaging. With Java, I've built a command-line task tracker, an expense tracker, and a tool that parses data from a code-hosting service's API. I'm currently working on a multithreaded HTTP server and a command-line text editor inspired by Vim. I also find the JVM fascinating and would eventually like to explore it deeply, perhaps even build a small JVM of my own.
What confuses me is how often people criticize Java, calling it bloated, boring, or unpleasant to use. I understand that Java may not have as many flashy language features as C++, Go, or Rust, but I find it straightforward and enjoyable. Why does Java have such a negative reputation, and are most of those criticisms aimed at the language itself, its ecosystem, or old Java development practices?
4 Answers
A lot of the reputation comes from Java’s history rather than from modern Java. Early Java was verbose, comparatively slow, and heavily associated with applets, desktop GUI programs, and enormous enterprise systems. Older Java development also involved XML configuration, complicated frameworks, and design patterns being applied everywhere. People who had to maintain those systems understandably remember the frustration.
Modern Java has improved substantially. Features such as records, lambdas, pattern matching, sealed types, and virtual threads make it much less cumbersome. It is still deliberately conservative and strongly focused on backward compatibility, but that stability is a major reason it remains so common in large systems.
Many people dislike the ecosystem more than the core language. Large Java applications are often built around frameworks with extensive annotations, dependency injection, reflection, generated code, and configuration. When everything works, that can provide powerful infrastructure. When something fails, the actual control flow may be hidden behind several layers and the error messages can be enormous.
Spring and similar frameworks are especially polarizing. They are useful for complicated enterprise applications, but they can make a simple HTTP service feel like it requires a huge amount of machinery. This is not uniquely a Java problem—large frameworks in other languages can create the same kind of abstraction overload—but Java acquired a particularly strong reputation for it.
That distinction matters: plain Java can be quite readable, while a framework-heavy application may be difficult to understand even for experienced developers. The platform’s popularity means there is also a lot of poorly designed legacy code attached to it.
The most common legitimate complaint is verbosity. Java often requires more ceremony than languages such as Python, Kotlin, or C#. Types, classes, interfaces, getters, setters, and explicit object construction can make small programs feel much larger than they need to be. Java’s object-oriented design can also encourage layers of factories, abstractions, and inheritance where a simple function would have been enough.
That strictness is not entirely bad. It makes large codebases easier to analyze and gives beginners a clear structure to work within. Whether the explicitness feels helpful or tedious depends a lot on what you value in a language.
Recent Java features help quite a bit. For example, records remove much of the repetitive code involved in simple data classes, and local variable inference can make declarations less noisy without abandoning static typing.
Java is popular partly because it is dependable, portable, well supported, and backed by a mature ecosystem. Those same qualities make it appear everywhere, including projects where another language might be more enjoyable. Developers often grow tired of using the same tool for every kind of job, especially when they are maintaining old systems rather than creating something new.
There is no reason to abandon it just because people make jokes about it. If you enjoy Java and the JVM, keep using it. Your projects—especially a multithreaded server, text editor, or bytecode interpreter—will teach you useful concepts regardless of what language enthusiasts prefer. You can always learn Kotlin, C#, Go, Rust, or another language later and compare their trade-offs yourself.

It’s also common for companies to remain on old versions for years, so developers may be criticizing Java 8—or even Java 6—while newer releases have already addressed some of their complaints.