There are a lot of articles explaining the theory behind Java generics, and whenever I read about these articles, I always feel confused, because I think it’s always confusing to learn about an abstract concept without concrete examples and actual use cases. Try reading Oracle’s Java tutorial on generics. I think I know generics fairly enough to be effective with generics and I still find the article confusing.
The concept of Java generics itself is a hard but interesting one to understand, and when articles start by telling people what it is and what the benefits are in some esoteric terms, it usually just doesn’t help me.
In this article, I’m going to take a shot at explaining generics by outlining why it was incorporated as a language feature in the first place Having said all of the above, you do need to have a vague sense of what generics are before jumping to my explanation below (i.e. you should have at least seen them and used them before).
So why are generics implemented in the first place anyway?
Most of us will get acquainted very early with Java generics through the use of Java’s collection library. Among the Java standard collections library, one of the most often used data structures in computer science is a list, which is an sequence of values. The following code snippet shows how you would declare some list of items in Java SE 6.
1 2 3 4 5 6
The class that you put in the angled brackets in the example above when
declaring the variable
names of class
List defines what the list contains.
In the example above, it’s
String. Formally speaking,
String is called the
type parameter of
List in this case.
Life Without Generics
Now, imagine how life in the Java world would be without generics. Imagine that angled brackets are the compiler’s worst enemy, and it will gladly let you know by throwing a barrage of syntax errors every time you put a left angle bracket after a type.
In the imaginary Java land, the example above transforms to the following:
1 2 3 4 5 6 7 8
Why do we have to use a temporary variable of type
Object to iterate through
the things in the list? If you were designing the implementation of the
class, you would need to declare some instance variable inside the class to
hold the items that will be put in the list.
To simplify things, let’s just assume that the instance variable in concern is
an array of items. What would the type of the item be? It can’t be an
String, or some specific data type, since then only people who
have the need of using an integer or string list can use your class.
Anyway, my point is that the type of the item has to be
is the superclass of all Java classes, it only makes sense to use
Now, you might say, “Well, that doesn’t seem too bad. I mean, we only need to
Object to a
String, right? Why deal with so much hassle to
implement these angle brackets?”
Imagine you’re still in the imaginary Java land, where generics are frowned upon. Being the good Java programmer you are, you implemented a class that looks like this, has good encapsulation, and all the good OOP stuff.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
For some (unclear) reason, you become famous, and you hire a programmer to
build you a website because you don’t have time anymore. And you told him to
Me class since it contains your personal info already nicely coded
in Java. However, it’s located in some private folder so you can’t give the
source code to your programmer, and all you can tell him is the method
signature of the class. You gave him a piece of paper with the following
written since you had to leave in a hurry.
1 2 3 4 5
Your fellow programmer then takes the note and the compiled bytecode, and goes ahead to code the website. Here’s what he came up with. Oh, and also, while he codes the website, he expresses his deepest inner thoughts with comments.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
Well, just in case you were wondering what happened to the aspiring Java
programmer, you fired him because his code did not work. It blew up with a
ClassCastException when you were showcasing the website during a press
Upon doing a code review, you found out about all his darkest thoughts and the
fact he did not use a
StringBuilder. And the only thing you got out of this
is the fact that afterwards his comments made you contemplate your silliness.
In all seriousness, please don’t code like him, it wastes valuable resources
trying to create a new
String when the only thing you really need to do is
string concatenation. Also, use a StringBuilder instead which is good enough
for single threaded operations to strings (it’s not thread-safe, but we’ll
leave that to another discussion).
Also, don’t comment on every single line. Please.
As contrived as the example above could be, not being able to share source code
is pretty common if you only have access to the JAR without the source. Also
only sharing method names is akin to sharing an interface of the class. It’s
sad, but class casting also happens in reality. While I realize class casting
sometimes cannot be avoided, it should be done in a safer manner using
instanceof only if you really need to (also, I won’t get into this, but
pattern matching provides a superior alternative to class casting).
The programmer’s sad ending could have been easily avoided if it were a couple years later and he was using Java SE 1.6, where the generics feature was added.
Really, the takeaway from the story above is that generics provide compile-time type safety. That’s a mouthful, but let me try to explain.
In the (albeit exaggerated) example above, the programmer could only have known that he had converted the object into the wrong type during run time. That is, after the code had been compiled and was running in some server, not until you click on the Autobiography link would the code have exploded.
Now, assuming the
getFavoriteThings() method had been declared properly using
generics as follows:
1 2 3
It would have been immediately obvious to the programmer that the type of the
Integer, and even if he still extracted the contents of the list using
a temporary variable of type
Object, assuming he knew how to program and has
some decent understanding that he can’t cast an
Integer to a
wouldn’t have done that.
The thing is to enable the compiler to warn you during compile-time if your types do not match (type unsafe operations) when you are coding by throwing a warning (or even better, an error), instead of seeing it happen during run-time. Hence the reason generics provide compile-time type safety.
Man, that was kinda fun! Hope this has helped you somewhat!
UPDATE: This article has been updated 1 time since it was first written.