Why is Java (but not .NET) unable to accommodate generics without the need for raw types / type erasure?
Asked Answered
L

2

5

My understanding is that the reason why there are raw types and type erasure in Java is that because at the time generics was introduced, there were standard APIs that could not be made generic without breaking existing code.

Generics was also introduced to .NET at some point down the road, but this feature was implemented in a manner that does not rely on raw types or type erasure (and if it does, it does so in a manner that is transparent to the user). So existing APIs remained unchanged (for example, the code in the System.Collections namespace) and new, generic APIs were introduced (for example, the code in the System.Collections.Generic namespace).

So how come Java generics, unlike .NET generics, requires raw types / type erasure?

Lillian answered 12/7, 2013 at 13:39 Comment(0)
T
8

.Net introduced generics by changing the bytecode language, virtual machine, and JITter to recognize generic types.
This was an enormous amount of work that took about two years.

Java introduced generics as a purely compile-time feature, with only small runtime changes (new metadata and reflection APIs).
This was a much simpler task, and it maintained backwards compatibility with older runtimes, but it's much more annoying to work with.

Thiele answered 12/7, 2013 at 13:41 Comment(4)
In addition, .Net replaced the existing containers with generic versions in a different namespace. Code that wants to use them has to be ported pretty much all at once. Java's way allowed them to simply make the existing containers generic, so porting bit by bit means just the occasional cast and warning suppression.Magnoliamagnoliaceous
@SebastianRedl: That's basically an extension of generics being a compile-time-only feature.Thiele
Although .NET changed the bytecode language, I don't think Java would have necessarily had to do so to allow generic objects to know their type. I would think it would have been possible for every generic object instance to contain one or more compiler-generated fields denoting the combination of types that instance had been instantiated with, and for the compiler to generated code that would validate such fields when appropriate. I think a bigger problem would that if an ArrayList<String> were implemented to be any type other than ArrayList...Foredate
...the only way for code which expects to use a non-generic ArrayList to hold a reference to the same collection as code which expects to use an ArrayList<String> would be to have ArrayList<String> be a wrapper around an ArrayList. Such a thing could work semantically, but unless the bytecode language was changed to facilitate it, some things would be rather slow (e.g. unless one added a field to ArrayList, converting an ArrayList reference to an ArrayList<String> reference would require looking it up in a static WeakDictionary).Foredate
S
3

Sun was especially keen to guarantee backward compatibility as the was a large established base of Java software. To do this they felt that the minimum of changes in the JVM was best. In hindsight, that doesn't appear to have been the best decision in the long run as it mean the JVM doesn't really understand generics and can't optimise away many redundant class checks.

Oracle by comparison have been less reluctant to change the JVM, and have suffered more serious and public bugs esp. to do with security. (They don't mean the same thing but one can lead to the other) Even so, Oracle have added just one instruction to the JVM which Java doesn't even use, whereas Sun added none so it is relative really. ;)

Microsoft on the other hand had a smaller code base for C# and customers more used to significant, even breaking changes between major versions. This means more pain in the short term but can be a better choice in the long term. You have less issues which are due to historical reason left around.

In short the difference is not technical, it is more political and historical.

Sanctus answered 12/7, 2013 at 13:54 Comment(1)
The difference is extremely technical.Thiele

© 2022 - 2024 — McMap. All rights reserved.