Donnerstag, 8. November 2012


Introducing Java Generics in Java 5 has been a big deal for Java developers. Avoid failures at runtime is the biggest challenge in software development. The best solution to avoid failures is to detect errors early at compile time. The compile time type check of generic collections is the real benefit of this Java feature. Get rid of the type casts  necessary by using legacy collections simplifies the development of software in the generic context.

Generics work by erasure which can be a weakness. The genius may use a leak to break the compile time type check by mixing legacy collections with generic collections. On the other hand the inexperienced programmer could make a programming error which breaks a generic collection as well. Anyway, we have the iron-cast guarantee and we know what we do, therefore we are safe. 

The reason to build Generics on erasure is the binary compatibility to legacy collections.  This reduces the migration effort from earlier Java releases to Java 5 software to zero. The possibilites range from using legacy collections with or without Generics and vice versa. Using Generics seems to be difficult. Programmers must learn some rules to have fun with Generics. One famous rule is the get-put-principle. Maurice Naftalin and Philip Wadler documented this rule in the book "Java Generics and Collections". Do you know that rule? Remember or learn:  extends = get, super = put and no wildcard get and put. Isn't it a funny gotcha.

Regarding the requirements of clean code, Generics fulfill the criteria for writing self-explanatory source code. Well, that sounds good, but I must admit it is only true when you have learned all these rules which can sometimes mutate to brain burner. 

Interesting is the influence of abstraction in case of Generics related to data. Why not abstract over behavior in the same way Generics abstract over data? First it seems we have a big gap. But we are already able to abstract over behavior. We know and use the Strategy Pattern (GoF-Pattern) and the possible implementation by using an anonymous class which can be threat as a function object (Joshua Bloch "Effective Java"). A function object can be used to implement the requirements of behavior abstraction which leads to Lamda expressions. The experienced programmer will say no: function objects are a similar technique but weaker compared to Lamda expressions and less readable. Again, that sounds good. But how about that little rules, we already know from Generics?! Ok, we will see and learn these gotchas.

 Spot on to light the following excerpt:

Generics allowed developers to better abstraction over types, the goal of Lamda is to help developer better abstract over behavior. [Brian Goetz, Oracle’s Java Language Architect]
Wow! But what’s behind that excerpt? The idea is simple to threat a chunk of code like a piece of data. Describing and characterizing a method in the same way in which you would declare and use a variable is a real benefit of Lamda. The possibility for passing a Lamda expression into a method like an ordinary type will fundamentally change the development of Java software.

I’m looking forward to Java 8 and the features which improve the Java developer toolset. This toolset has additional features like the virtual extension methods which provides to implement default methods for interfaces. Default methods for interfaces mean methods with a body! That's sounds strange but why not? It is simply the support  for interface evolution to maintain binary compatibility with classes already compiled with older interface versions. Older binaries work with the new default interface methods without the requirement of recompilation. Great, no more nightmares with public interfaces.

Thank you for your attention! See you next time! I promise to publish more source code next time to discuss Java topics which is clearer than plain text.