Posts Tagged ‘Anti-Patterns’

Anti-Patterns once again

December 9, 2009 Leave a comment

I just stumbled over another list of interesting Java Anti-Patterns. Luckily I agree with all of them, so unlike the last time, I can just link them here.

Categories: Programming Tags: ,

Java Anti-Patterns revisited

December 8, 2009 5 comments

Today I’ve stumbled over an interesting Homepage that contains a section about Java Anti-Patterns. It’s really well written and funny to read. Unfortunately it also contains some advises that I cannot agree with at all:

Lists are overrated: I would say quite the opposite: Prefer lists to arrays unless you have a very good reason not to. Arrays might perform considerably better in some cases, but they are far more easily used incorrectly (because of a major design flaw) and don’t mix well with generics. Also, programming against the List interface is more convenient and adds an additional layer of abstraction that allows you to change the actual List implementation easily. EffJava2 dedicates Item 25 to this topic alone.

Hashtable, HashMap and HashSet are overrated: I cannot agree here too: Yes, the entry wrappers are bigger than one might initially expect as they contain an additional forward reference and a cache for the hash code. And yes, HashSet is in fact implemented using a HashMap. I have to admit that this made me a bit curious, so I looked at the corresponding implementations in libstdc++ for unordered_map and unordered_set. What I found out is that they are using basically the same entry wrappers, although they let you decide with a C++ template parameter if the hash code is cached, which is false by default. Here is a comment found in one of the related headers:

// Nodes, used to wrap elements stored in the hash table. A policy
// template parameter of class template _Hashtable controls whether
// nodes also store a hash code. In some cases (e.g. strings) this
// may be a performance win.

To be fair however, it should be noted, that the C++ implementation does not waste a pointer if caching is disabled. Also, although they too use a shared implementation for unordered_map and unordered_set, C++ templates allows them to do this without wasting any space for sets, or doing lots of casting (which would be unavoidable if one tried the same approach in Java). To cut a long story short: The implementations that are shipped with the Java standard library aren’t that bad at all, they just reflect the fact that Java isn’t C++, which features a turing complete, code generating metalanguage via the template mechanism, that looks like Java generics only on the surface. Should your analysis reveal that the Java implementations of HashSet and HashMap generally (not only in a few hotspots) waste too much space, then most likely Java isn’t the right tool for your task at all. Otherwise just use HashMap and HashSet and don’t care about the memory overhead, which isn’t that bad as long as you don’t store small objects in these containers. Using exotic Map implementations like IdentiyHashMap is the right thing to do only in rare occasions, because IdentiyHashMap intentionally violates Map‘s general contract which is normally not what you want.

Not properly propagating the exception: Here the author claims that you may loose information if you do

catch(SomeException e)
    throw new RuntimeException(e);

instead of

catch(SomeException e)
    throw new RuntimeException(e.getMessage(), e);

which is true in theory for the detail message of the constructed RuntimeException, but should happen in practice only if SomeException overrides Throwable.toString() or Throwable.getLocalizedMessage() in a rather obscure way. I’m not aware of any exceptions that do this (and if I was I would rather fix them), but maybe I missed something, so please correct me if I’m wrong.

Too much static: In this item the author makes an interesting point about storing loggers in static fields prevents unused classes from being garbage collected. This sounds perfectly reasonable and caused me some headaches as I always store loggers in static fields. Some research however revealed, that it is not true. Let me cite the relevant part from the Java Language Specification:

A class or interface may be unloaded if and only if its defining class loader may be reclaimed by the garbage collector as discussed in §12.6. Classes and interfaces loaded by the bootstrap loader may not be unloaded.

So abandoning static loggers won’t change anything as far as class unloading is concerned. Storing loggers in normal instance fields on the other hand side can be annoying in entity beans and can cause screwups with serialization, as correctly pointed out in The transient trap. So my advice here is: Just store your loggers in private static final fields, and be done with it. Should you ever have the need to access the logger of a superclass, you can still obtain it explicitly by something like

Logger log = LoggerFactory.getLogger(getClass().getSuperclass());

although I don’t know any usecase for this other than someone deliberately obfuscating the source of the log messages.

Categories: Programming Tags: , ,