What’s wrong with Java?

OK, so I’ll admit a lot of my posts so far have been links to other articles, along with my notes and opinions on them.  While I don’t feel guilty about that (as long as I’m adding value or finding content others might not have found), I’m going to try to add more original content.

I love Java, but there are a few very large issues I have with it.

  1. Container sizes: There are many kinds of containers that can hold other things in Java, and that’s wonderful.  But there are certain things that are common between them, that have different names, and there’s just no excuse for that.  The biggest offender though, is what you call to find out how many things are in the container.  For some it’s .size(), for some it’s .length(), for some it’s .length or .size (attributes instead of methods).  There are other examples, like .contains() vs .containsKey()/.containsValue().
  2. Garbage collection: Managed memory is great.  The main problem with Java’s garbage collection is more about the myths and perceptions.  Many developers think that .finalize() will always be called, which simply isn’t true.  Your objects may never be garbage collected.  Another very common problem is obsolete references to object preventing them from being garbage collected.  There’s an excellent section on that in the book Effective Java, which I mentioned in this post.  Another section goes into how easy it is to make a reference to an object, when you really meant to make an identical copy.  Even clone() does shallow copies.  Not very intuitive.
  3. CLASSPATH confusion: One of the main attractions of Java for me is how cross-platform it is.  Imagine my disappointment when I heard that the CLASSPATH environment variable require different delimiters.  Beyond that, there’s much confusion in the minds of newbies over what can be in a CLASSPATH.  Lots of examples show specifying .jar files in the CLASSPATH, and some show directories, but when you specify a directory, does it automatically look in look in subdirectories?  It turns out the answer is “Yes, but only for some things”.  Here’s some documentation for Solaris, for instance that should clear everything up 😉 :

    A class path entry that contains * will not match class files. To match both classes and JAR files in a single directory foo, use either foo:foo/* or foo/*:foo. The order chosen determines whether the classes and resources in foo are loaded before JAR files in foo, or vice versa. Subdirectories are not searched recursively. For example, foo/* looks for JAR files only in foo, not in foo/bar, foo/baz, etc.

  4. Generics:Generics were a great idea, but like so many physics models of the universe, they run into trouble with the edge cases, in part in the name of maintaining backwards compatibility.  For instance, today I was trying to get rid of some “unchecked” warnings on this one project.  I got rid of most, but there was this one area where we need to use the class loader to get an instance of a class by its name.  That class is a container class, though, and we’re using generics to allow that container to hold different kinds of objects which all have the same parent class.  I could have hired the infinite number of monkeys (once they’ve finished typing all of Shakespeare) to try all combinations of where to put the <Foo>.  After much research, I never did find an answer.  I’ll post it on some mailing list when I get bored enough.
  5. Java hates nouns: One of the most brilliant and hilarious articles on Java I’ve ever read covers this fully here, so I won’t attempt to cover it further, as my missive surely would not compare.
  6. Getters and setters and .clone()s! Oh my!: If I had a nickel for every getter and setter I had to write with less than three lines of code in them, I would be able to fill my car’s tank with gas!  Maybe  even twice.  It’s things like this that attracted people to Ruby On Rails, which relies on naming conventions to kinda figure out what you want, and automatically provides the functionality.  Fortunately those crafty JavaHeads like to steal from the best, and have created  things like Grails to steal their thunder.

There are some very wonderful things about Java, though, and that’s why most of what I’ve written in the past few years (modulo some PHP web work) has been in Java, be it for the web, the desktop, or the command line.

  1. The swissarmyknifishness of it:  If you want to do something, there’s most likely either a built-in class/method to do it, or some standard add-on technology.  I used to hate hunting down some library written by a grad student with no clear license or clear intent to maintain it when I worked more in C and C++ and other languages like them.
  2. JavaDoc: It makes it easy for the “sincere but lazy” to throw in some quick notes in a way someone might actually be able to use them one day.
  3. Single inheritance: A bit of a hot topic, but I’m behind it all the way.  It has, on more than one occasion, made me realize I was going about something all the wrong way.  If you’re trying too hard to fit your model into single inheritance, you’re most likely doing something wrong.
  4. XML: Java is very good at dealing with XML, which is ubiquitous today.
  5. Very little use of punctuation marks: I used to be a huge Perl-head, and largely for the same reasons I like Perl now (except I was into Perl before it was as strong in OO as it is today, which is not as much as I would like, but that’s a post for another day).  But the more I needed to work on other people’s Perl code, the more I got frustrated how the different combinations of punctuation marks surrounding a variable name drastically changed the meaning.  I found it made reading other people’s code much more frustrating, like reading science fiction with 10% of the words being from some alien language.  “Clever” Perl programmers will use all sorts of derefrencing prefixes it looks more like bleeped out curse words than code.  It practically begs the developer to write code that looks small and elegant and completely obfuscated to anyone else, or even the author a year later.  So I am very glad for Java’s lack of such things.  Making everything look like a method/function or attribute can be a little more verbose, but I see that as a feature.

So what do you think?


1 comment

  1. This is a really excellent post. While Java does indeed have a few design problems, it’s a darn good tool and when used well can be as much of a Swiss Army Chainsaw as any other language 🙂

    You mention the awesome Effective Java book in your post, and for anyone who’s read that and enjoyed it, they might find this Google I/O talk useful and interesting:


    I’m embarrassed to say that I haven’t really wrapped my head around Java generics yet, hopefully soon 🙂

    Also I agree entirely with regard to the getters and setters, lots of IDEs take care of most of the drugery for you but still it’s a DRY problem. As you said, languages like Groovy and Ruby handle this much more elegantly.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.