I understand that generics are checked at compile time and that this prevents runtime exceptions by not allowing code with faulty generics to be compiled in the first place. When compiling, the compiler will, upon confirmation that generics have been implemented correctly, convert the generic types to raw types. Why? I'm trying, unsuccessfully, to reason what the benefit of this conversion is. Does anyone have a explanation?
-
4Backward compatibility. Old code that doesn't use generics needs to be interoperable with new code that does, and old JVMs wouldn't understand generic bytecode. – user2357112 Feb 04 '14 at 10:36
-
@user2357112 that's right, post it as an answer not a comment please. – Xabster Feb 04 '14 at 10:37
-
[Type Erasure](http://docs.oracle.com/javase/tutorial/java/generics/erasure.html) - "Replace all type parameters in generic types with their bounds or Object if the type parameters are unbounded. The produced bytecode, therefore, contains only ordinary classes, interfaces, and methods." – Mr. Polywhirl Feb 04 '14 at 10:38
-
1They wanted to avoid modifying JVM. IMO, that was one of the stupidest decision made by the Java steering committee. – Sergey Kalinichenko Feb 04 '14 at 10:39
3 Answers
Because generics weren't made part of Java from the beginning (1.0). If it was, it would have been implemented using Reification. Quoting Bruce Eckel's 'Thinking in Java':
In reality, even if programmers are only writing generic code, they will have to deal with non-generic libraries that were written before Java SE5. The authors of those libraries may never have the incentive to generify their code, or they may just take their time in getting to it. So Java generics not only must support backwards compatibility—existing code and class files are still legal, and continue to mean what they meant before—but also must support migration compatibility, so that libraries can become generic at their own pace, and when a library does become generic, it doesn’t break code and applications that depend upon it. After deciding that this was the goal, the Java designers and the various groups working on the problem decided that erasure was the only feasible solution. Erasure enables this migration towards generics by allowing non-generic code to coexist with generic code.

- 472
- 4
- 13
As you can read on http://www.artima.com/intv/generics2.html Java generics initial purpose was to run on an unmodified VM. That's why generics are handled by the compiler.
Java's generics implementation was based on a project originally called Pizza, which was done by Martin Odersky and others. Pizza was renamed GJ, then it turned into a JSR and ended up being adopted into the Java language. And this particular generics proposal had as a key design goal that it could run on an unmodified VM [Virtual Machine]. It is, of course, great that you don't have to modify your VM, but it also brings about a whole bunch of odd limitations. The limitations are not necessarily directly apparent, but you very quickly go, "Hmm, that's strange."
You should read about Type Erasure and how it deal with raw type. Consider the following code:
MyNode mn = new MyNode(5);
Node n = mn; // A raw type - compiler throws an unchecked warning
n.setData("Hello"); // Causes a ClassCastException to be thrown.
Integer x = mn.data;
After type erasure, this code becomes:
MyNode mn = new MyNode(5);
Node n = (MyNode)mn; // A raw type - compiler throws an unchecked warning
n.setData("Hello");
Integer x = (String)mn.data; // Causes a ClassCastException to be thrown.
Here is what happens as the code is executed:
n.setData("Hello"); causes the method setData(Object) to be executed on the object of class MyNode. (The MyNode class inherited setData(Object) from Node.)
In the body of setData(Object), the data field of the object referenced by n is assigned to a String.
The data field of that same object, referenced via mn, can be accessed and is expected to be an integer (since mn is a MyNode which is a Node.
Trying to assign a String to an Integer causes a ClassCastException from a cast inserted at the assignment by a Java compiler.
you can read about type Erasure here : http://docs.oracle.com/javase/tutorial/java/generics/erasure.html

- 3
- 3