#blog
Table of terms and their scariness
It is important to understand that Java generics is not true generics, it offers only syntactical support to take advantage of compile time safety check. All generics gets compiled to non-generic code during byte code generation.
In the beginning, Java doesn’t support generics, and this is how you would manipulate a List: https://gist.github.com/2f64727c74d63959280943d72b4c5f0c
Notice that it is exactly the same as how one would write the code pre-Java 5. You can think of Java generics as syntactic sugar over using raw type and manual castings.
With Type-Erased Generics, you get
- Compile-time safety check 👌
- Backward compatibility with pre-Java 5 code 👌
- No type information available at runtime 😢
Reification sounds like a term that software people invented to protect their job. This is the definition of Reify from Merriam Webster,
to consider or represent (something abstract) as a material or concrete thing
Reification is the opposite of type erasure, it is the process of making type information available at runtime. Java supports reification for most of the types, like primitives (int, char) , non-parameterised type (Number, InputStream), array of primitives (int[]), etc. These are called Reifiable Types, they retain their type information at runtime, because they are not subjected to type erasure.
The following 2 types are NOT Reifiable Type:
- Exact Parameterised type - List
- Bounded parameterised type - List<? Extends Number> They lose their parameterised type information at runtime due to type erasure.
Reifiable types in action https://gist.github.com/a1e760088948b972ec7084ccff61d109
Non-Reifiable types in action https://gist.github.com/3a1ce22cc7840b132a9ded2b51512fa1
Reified Generics is the type of generics system that makes generics type information available at runtime. C# is one language that supports Reified Generics natively, as opposed to Java’s Type-Erased Generics.
There are, however, some obscure dark magic that allows you to make reified generics happen in Java using Type Token, but that belongs in the Restricted Section.
Let’s take a look at what is possible if java were to support Reified Generics.
https://gist.github.com/435312a74e4deb0a59e712ea633023fe
The 2 non-reifiable types above will have their type reified https://gist.github.com/4448ef9cd8d577601f060819c2d0c5d2
https://gist.github.com/ab6061e0e9a8dc7eb152c92a120a545f
Sometimes we get a warning about using raw type in the IDE https://gist.github.com/804bba4d106f2726b27620a39f4e2636
Raw type is basically the use of generic without type parameter. It was ubiquitous before Java 5, but with the introduction of generics, the added benefit of compile time checking is completely subverted by the usage of raw type, defeating the purpose of generics.
Notice how this is a merely a warning instead of error, because raw type is known to be potentially dangerous, nevertheless, it is allowed for backward compatibility with pre-Java 5 code.
Usage of raw type could lead to Heap Pollution, which in turn produces ClassCastException™️. There is even a rule from Effective Java - Item 26: Don’t use raw types.
Another simple concept with a complicated name. Heap pollution happens when a variable of type X doesn’t point to X or its subclass, but points to Y. How is this even possible with a strongly typed language? Well, because Java allows you to use Raw Type!
Consider the following code: https://gist.github.com/479f699607ba1fe179510f9a2c5645ae
In line 2, strList is pointing to a list of integer (intList), but compiler doesn’t complain because it doesn’t know that intList is a list of Integer due to the use of raw type in line 1. When you’re getting string out of strList, ClassCastException happens. In a way you are “polluting” the heap by putting a type where it shouldn’t be.