Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What are Reified Generics? How do they solve Type Erasure problems and why can't they be added without major changes?

I've read Neal Gafter's blog on the subject and am still unclear on a number of points.

Why is it not possible to create implementations of the Collections API that preserve type information given the current state of Java, the JVM and existing collections API? Couldn't these replace the existing implementations in a future version of Java in a way where backwards compatibility is preserved?

As an example:

List<T> list = REIList<T>(T.Class); 

Where REIList is something like this:

public REIList<T>() implements List {   private Object o;   private Class klass;    public REIList(Object o) {     this.o = o;     klass = o.getClass();   } ... the rest of the list implementation ... 

And the methods use Object o and Class klass to get the type information.

Why would preserving generic class information require language changes rather than just a JVM implementation change?

What am I not understanding?

like image 874
sal Avatar asked May 18 '09 21:05

sal


People also ask

What is reified generics in Java?

Reified Generics is a 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.

What is generic type erasure?

Type erasure is a process in which compiler replaces a generic parameter with actual class or bridge method. In type erasure, compiler ensures that no extra classes are created and there is no runtime overhead.

Are reified generics and type erased generics same?

The whole point is that reified generics have support in the compiler for preserving type information, whereas type erased generics don't. AFAIK, the whole point of having type erasure in the first place was to enable backwards compatibility (e.g. lower versioned JVMs could still understand generic classes).

Why are generics implemented using type erasure?

Generics were introduced to the Java language to provide tighter type checks at compile time and to support generic programming. To implement generics, the Java compiler applies type erasure to: Replace all type parameters in generic types with their bounds or Object if the type parameters are unbounded.


2 Answers

The whole point is that reified generics have support in the compiler for preserving type information, whereas type erased generics don't. AFAIK, the whole point of having type erasure in the first place was to enable backwards compatibility (e.g. lower versioned JVMs could still understand generic classes).

You can explicitly add the type information in the implementation, as you have above, but that requires additional code every time the list is used, and is pretty messy in my opinion. Also, in this case, you still don't have runtime type checking for all of the list methods unless you add the checks yourself, however reified generics will ensure the runtime types.

like image 78
ghempton Avatar answered Oct 08 '22 22:10

ghempton


Contrary to beliefs of majority of Java developers, it is possible to keep compile-time type information and retrieve this information at runtime, despite in a very restricted way. In other words: Java does provide reified generics in a very restricted way.

Regarding type erasure

Notice that, at compile-time, the compiler has full type information available but this information is intentionally dropped in general when the binary code is generated, in a process known as type erasure. This is done this way due to compatibility issues: The intention of language designers was providing full source code compatibility and full binary code compatibility between versions of the platform. If it was implemented differently, you would have to recompile your legacy applications when you migrate to newer versions of the platform. The way it was done, all method signatures are preserved (source code compatibility) and you don't need to recompile anything (binary compatibility).

Regarding reified generics in Java

If you need to keep compile-time type information, you need to employ anonymous classes. The point is: in the very special case of anonymous classes, it is possible to retrieve full compile-time type information at runtime which, in other words means: reified generics.

I've written an article about this subject:

http://rgomes-info.blogspot.co.uk/2013/12/using-typetokens-to-retrieve-generic.html

In the article, I describe how our users reacted to the technique. In a nutshell, this is an obscure subject and the technique (or the pattern, if you prefer) looks extraneous to majority of Java developers.

Sample code

The article I've mentioned above has links to source code which exercises the idea.

like image 22
Richard Gomes Avatar answered Oct 08 '22 20:10

Richard Gomes