In addition, the given reason for implementing
generics using erasure is fraught with logic
problems.
The proposed reasoning is to preserve backward
compatibility so that code compiled with generics
will
be able to be run on lower version virtual
machines.
However, the fact is that in order for that to
happen,
the user would have to replace the rt.jar at the
very
least; since the 1.5 code could not only be using
generics but other features of 1.5 such as the new
APIs.
The main reason is to allow existing source and class
files to interoperate with new source and class
files.
Again, the source files shouldnt be affected unless you intend to completely remove non-generic sets from the JDK. I had not hear that this would be the case. If those collections are still in the JDK then the only code would merely use them like normal. Erasure does nothing to help legacy source files unless I am missing something critical. If I am, please elaborate on exactly what incompatibility would exist without erasure. Lets have some code examples and explanation.
To add more fuel to the fire, the developers of the
JDK have already decided to break backward
compatibility; so why are they keeping backward
compatibility in generics when the other code
prohibits backward compatibility. Its a paradox.
We have not broken backward compatibility with the new
language and VM changes. Existing source and class
files will run in 1.5 without problems.
You misread me. I said that new source files wont compile on older JDKs already. I still see no reason that old source files couldnt compile on the new JDK wihtout erasure. Erasure is a compile time issue, not a runtime issue.
In fact, erasure seems to have no technical grounds whatsoever. I challenge you to prove such grounds because everything I read in the spec and in the forums about the need for erasure simply doesnt wash.
So what if we dont do erasure? What is the problem
with that? The compiler would generate class files
that are in addition to the normal class files in a
similar manner as it generates invidual classfiles
for
inner classes. What is the downside? More binary
release volume? In return for type safety and the
ability to continue to use the most powerful tool
in
the jdk (reflection)? Sold. Put me down for a dozen.
The main problem is that all of your existing
applications that use generics would require source
file changes and then need to be recompiled.
Why would you need source changes? Can you give me an example of an old source file that wont compile under the new JDK without erasure?
Existing
sources and binaries would not run properly.
Again why? The existing binaries would be using the old type-unsafe sets. Why would they not run properly?
I implore sun to say, "Uhh ... nevermind that
erasure
stuff." It will simplify the implementation of
generics greatly and simplify the learning curve
required for generics. In addition,it will preserve
the power of reflection.
We can't simply say nevermind to erasure without a
specific implementation strategy to replace it, and
you haven't suggested one.
Yes I did but perhaps I wasnt clear. Its simple. For every construct like:
Set<String> strs = new HashSet<String>;
The compiler generates a utility class (note CLASS files and not source files) that looks like:
public interface Set$$Integer {
boolean add(Integer o);
// ... etc
}
public class HashSet$$Integer implements Set$$Integer {
boolean add(final Integer o) {
// .. code
}
// ... etc
UnmodifiableHashSet$$Integer {
// get methods but no set methods.
}
}
And then the only question is how do you get unmodifiable sets. This can be fixed with an easy change to the jdk.
1) Deprecate collections.unmodifiableSet() and the similar methods.
2) Implement new method in the interface for Collection and Map
public interface Collection {
// .. other collection methods
// this is added.
/**
* Retrieves an unmodifiable version of the collection.
*/
public Collection unmodifiable();
}
3) implement this method in the legacy sets as well as in the new sets.
4) Implement a typesafe version on the generated collections. ie ...
public interface Set$$Integer {
boolean add(Integer o);
Set$$Integer unmodifiable();
}
5) Implement this method in the code base for the typesafe sets.
6) Implement methods in the generated set for converting to a non-typesafe set.
7) Compile the generated classes and put them in a special package with a special name like "generics.generated". Let the user give to the compiler an option for what package to put the generated files in as well. (The reason they go into one package is so that if 4 classes use HashSet<String>, we dont want 4 copies of the class in the code.)
There you go. There are some minor details but nothing serious.
What this would accomplish is that it would obviate the need for erasure. Currently there are code generators that do exactly this. It doesnt seem that hard to do. There are some details to be worked out but it would work very well.