Sign up to gain exclusive access to email subscriptions, event invitations, competitions, giveaways, and much more.
Slow startup times, null pointers, security flaws -- Java's ongoing success leaves plenty to complain about
15 things we hate about Java
We don't really hate Java. It's the best thing that's happened to us. We love its type-checked, belts-and-suspenders world for the stability and ubiquity. But that doesn't mean we can't complain a bit and dish out the snarky, cranky comments, does it? Isn't that why the Internet was invented?
Here are 15 complaints about the write once, run mostly everywhere language that Java has become.
Long CamelCase names
The idea of gluing together long sentences into variable names by capitalizing the first letters gets old quickly. There's no doubt that it adds a bit of self-documentation to the code but wouldn't it just be easier to read a line that said:
i // holds the interest rate before taxes as per regulation 43
If there's one major difference between Java and the newcomers, it’s the punctuation. Java programs are filled with curly brackets, semicolons, and parentheses that other languages like Groovy or Ruby do well without. Not that punctuation lovers don’t have a legitimate beef with languages like Python that use arcane white-space rules to signify the same separations between expressions and blocks that punctuation does in Java, but still, most programmers just can't stand the punctuation. They see it as visual noise -- and an opportunity for the compiler to scold and scold again. This disconnect means there may be no easy solution beyond letting some folks use Groovy and others use plain old Java. At least their code can compile into the same JAR.
Open source confusion
Is Java open source or not? Just which libraries are open source? Darned if I can be sure even after Google's long skirmish with Oracle. For the most part, Java programmers don't need to worry because the JREs and JDKs are freely available. But in the backs of our minds, there's always the scary feeling that some lawyer will jump out of nowhere and say, “Stop!” Somehow it feels like the legal status makes us all pawns in the battles between IBM, Oracle, and Google.
The Java thread pig farm
When Java came along, the threads were lightweight compared to many of the other solutions. They were an easy way to juggle multiple tasks with the same memory space. Now, the folks using Node.js are always sticking their tongue out at the Java server platform and suggesting that the Java thread factory is one big pig farm adding 2MB of fat to the server RAM profile every time someone clicks on a Web link. Somehow, using the Java thread model is never as lightweight as it used to be. (Not that any of us still programming in Java are either, but that doesn't make it easier to live with.)
Intolerably slow startup times
Anyone who's tried to create an Android app using Java knows how slowly the simulator code runs on your desktop. That's just the most extreme example of how getting a Java program going is about as hard as getting a teenager to get up early on a Saturday to clean their room. While Java apps can run fairly smoothly once they get going, they start up slower than an overladen 18-wheeler at a red light on an uphill road.
Endless checking for null pointers
Is there anything to this complaint? Let me check if it's null before typing any more. Seems fine. Now let me check if my keyboard is still here and hasn't been replaced by something null. It's still here. Now I'll move my fingers and tell you why null testing is a pain.
Java requires endless if statements to test whether variables have ended up null; otherwise entire threads crash with NullPointerExceptions. Smartass developers say it's my fault for not checking the input at the beginning, but that's often not possible when creating libraries. If someone picks up this class file in the future, you better check all the variables yet again, because you have no idea how they will reuse it.
Object creation overhead
Tossing everything into an object seems like a clean way to program until you realize just how slow it can be to create a Java object. Everyone who really tries to re-engineer code to speed it up begins by tossing aside the object-oriented model as much as possible. Object creation is relatively expensive, and it’s a big reason why some Java code runs so slowly.
Primitive wrappers to use data structures
The Java Collections classes and other data structures are nice, but they require you to wrap your basic values in objects to use them. That means a four-byte int turns into a big fat object with all the weight and creation time of an object. Some programmers have written their own data structures with basic primitives to avoid this issue, but it's probably too late for mainstream Java. We're stuck with making the distinction between a four-byte int and an Integer object.
Strings are big, need overhead, and are final
Strings are yet another object, but they can't be changed. You better get them right the first time. If you want to change one byte, you've got to create an entirely new object and copy it all over. Plus, they add some overhead, which is fine for tossing around big blocks of text but a real nuisance for small strings. Do you get a choice? Nope. Just be happy that the overhead with the start and stop points comes in handy when you're snipping and concatenating.
No global variables
It's a bit disingenuous for programmers to complain about the lack of global variables in Java because they're also quite willing to grouse about the dangers of global variables in other languages like PHP. Still, we're forced to jump through some strange hoops to do much of what global variables will give us. Some people create a Global class and fill it with static variables. Others build singleton objects complete with a getting routine that will always return the one object. This might be tolerable if creating singleton objects weren't so fraught with race conditions and issues about efficiency.
Some say it's not fair to blame Java for the fact that it's a big target. Others say that the other platforms have even more security holes and at least the Java engineers tried to build a decent sandbox. Still others say security issues are expected, and at least Oracle publicly announces bug fixes, often in big batches like the 42 security fixes it announced last year.
These are all fair points, but they don't make living with Java any easier. Java's popularity means that many hackers will target the JVM. Java's security model means that many programmers will trust the JVM when perhaps they shouldn't trust it so blindly. If only we could believe that the software was perfect.
Many languages now compile down to Java bytecode so they can run on any JVM. What better way to draft behind the hard work the Java team does to ensure compatibility and ensure your code can run on a variety of platforms? Clojure, Scala, JRuby, Rhino -- the list goes on and on.
This can be an advantage for integrating, say, Ruby with Java, but it inevitably turns into a hassle. Suddenly it's not enough to make sure the Java code compiles with the libraries you've got. Now you've got to worry about N languages running peacefully in the same JVM. When it works, it's a testament to the power of the Java stack, but it can be a headache generator for everyone.
Self-improvement is normally an occasion for celebration but in the world of the Java stack, it can also bring confusion and headaches. Should I use the newer StringBuilder class or the older StringBuffer? Or is StringBuilder the older one? Aren't they the same? At least it's easier to remember that the new IO classes, NIO, are newer than the old ones. There are dozens of examples of new and improved techniques that you might want to use, if you can keep everything straight. They keep improving the Java stack, but this only means we need to relearn so many of the idioms that were burned into our brains before.
The huge collection of official Java APIs and not-as-official open source packages from groups like Apache make Java a fertile environment for standing on the shoulders of giants. The only problem is that you can't stand on the shoulders if you don't know they exist. It can take days to work through the various APIs to figure out which is really the best for what you're trying to do. And then the guy in the other cubicle always seems to know something better, a fact that will always be delivered with just the slightest amount of snark at the code review meeting.
Java is everywhere
Java is everywhere, they say. It's in cell phones, Blu-ray disks, Hadoop clouds, and desktops. Shouldn't that be a cause to celebrate? Doesn't that mean everyone loves it? Sure! But it also makes it easier to hate because all that success makes it that much harder to keep a handle on it all. It's a full-time job just watching the Java world evolve. Quick, what do you need to fix when you upgrade from 1.6 to 1.7? Which version of the Apache Commons is good enough? It's just not possible to be a Java expert anymore, and that's a tough revelation for those who could be Java experts back when the language appeared.