views:

448

answers:

3

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 a implementations of the collections api that preserve type information given the current state of Java, the JVM and existing collections API? Couldn't these be them 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?

+2  A: 

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 compatability (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.

Gordon
It's source and object code written for older JVMs can run on new JVMs without any changes (source code will have problems with "enum" as identifier, but that isn't generics as such).
Tom Hawtin - tackline
+2  A: 

IIRC (and based on the link), Java generics are just syntactic sugar for the existing technique of using an Object collection and casting back and forth. It's safer and simpler using the Java generics, since the compiler can do the checks for you to verify that you maintain compile-time type safety. Run time, however, is an entirely different problem.

.NET generics, on the other hand, actually create new types - a List<String> in C# is a different type than a List<Int>. In Java, under the covers, they are the same thing - a List<Object>. This means that if you have one of each, you can't look at them at run time and see what they were declared as - only what they are now.

The reified generics would change that, giving Java developers the same capabilities that exist now in .NET.

Harper Shelby
I put your List<*>s in backquotes so the types would show up.
David Zaslavsky
@David - thanks. As many times as I've done that for someone else, you think I'd remember...
Harper Shelby
A: 

I'm no expert on the subject, but as I understand it the type information is lost at compile time. Unlike in C++, Java does not use a template system, type safety is achieved entirely through the compiler. At runtime, a List is actually a List, always.

So my take is that a change in the language specification is required due to the fact that the type information is not available to the JVM because it isn't there.

n3rd