I bash Java. A lot. So now, I’m going to take a bit of time to mention something positive:

Java generics combined with the enhanced for loop. It makes me feel like I’m working with the C++ Standard Template Library, and that’s a happy feeling.

Some people don’t like generics. Ken Arnold considers them “harmful” (seriously, that phrase should not be used anymore). I suppose Java was originally designed for blubs like Ken. The C++ community has been working with the same notion for significantly longer (where do you think the syntax came from?), and I don’t quite see anyone complaining about the STL‘s complexity. Rather, it’s a very simple and elegant way of abstracting basic algorithms.

Some concrete reasons in favor of using generics:

  • Type checking is pushed to compile time. The more checks that can be done at compile-time, the less risky a piece of software is. Generics allow a function to be provably type-safe by removing all casts.
  • They provide executable documentation, which is the best kind. I just converted some of my own code to use generics, and I found that I was already describing the data structures in comments anyways: Map matrix; // map(int -> map(int -> int)). Converting to Map<Integer, Map<Integer, Integer>> matrix means that the type documentation will never go out of date, as it is required for compilation. If I changed to a matrix of floats or longs, my comment would have probably fallen by the wayside, and wrong documentatio is arguably worse than no documentation.
  • They reduce visual complexity. There is a bit of duplication when declaring a new object: Map<Integer, Map<Integer, Integer>> matrix = new HashMap<Integer, Map<Integer, Integer>>(); That occurs much less frequently than data structure traversal, which (with generics) now has the advantage of avoiding typecasting. It’s not bad to see a bit of verbosity at the top of a function where my mind’s not invested in something, but I really hate trying to wade through a long algorithm and seeing language boilerplate clutter up my screen. Generics also go hand-in-hand with easy-reading iterables:
    for (Integer row: matrix.keySet()) {
    for (Integer col: matrix.get(row).keySet()) {

    This is on par with iterators from other imperative languages (C++, Python, and PHP, though C++ is the only one to standardize on ranges for iteration).