Forum Stats

  • 3,851,385 Users
  • 2,263,969 Discussions
  • 7,904,691 Comments

Discussions

How Generics compiled to libraries?

843793
843793 Member Posts: 41,732 Green Ribbon
edited May 27, 2003 9:03PM in Generics

I haven't work with Java generic, but think it's very similar to C++.

Here's my question. If I create a class with generic, something in C++ would be:
template<class T>
class Test{
   T myitem;
}
If I compile this class for reuse later, how the generated class file would be? It seem to me that the class file format must be different, because it has to store generic information (such as class T). Would this one show that it can not be compatible with old JRE? I heard Sun now decides not to support forward compatibility. That's ok. But regardless, would this thing prevent forward compatibility (in case Sun decide to support it).

I maybe way off. Such as you can not compile such a thing into library for used later on. But if that's the case, then java generic is very limited then.




Comments

  • 843793
    843793 Member Posts: 41,732 Green Ribbon
    The compiler puts the generics information in attributes that will be ignored by older JVMs.

    What you're hearing about Sun not supporting compatability is that 1.5 source code compiled with javac will not run ion older JVMs. Other compilers are free to allow 1.5 source to run on older JVMs, and there are no changes to the JVM to support generics beyond supporting some new reflection calls that involve generics.
  • 843793
    843793 Member Posts: 41,732 Green Ribbon
    What you're hearing about Sun not supporting
    compatability is that 1.5 source code compiled with
    javac will not run ion older JVMs. Other compilers are
    free to allow 1.5 source to run on older JVMs, and
    there are no changes to the JVM to support generics
    beyond supporting some new reflection calls that
    involve generics.
    Maybe. The new GJ prototype will change the type system substantially (from what I've heard) and it is quite possible these changes will be (more) incompatible with old JVMs --- actually probably with old class libraries moreso than the JVM itself (but maybe not). As an example, say that arrays are newly defined to be instanceof Collection, so that 'new Integer[] instanceof Collection<Integer>' is true. You will likely be unable to run this code correctly on old VMs. A smart compiler might be able to make most current GJ code run on older VMs still, but anything which uses the new features (includes an expression like 'new Integer[] instanceof Collection<Integer>', say) would not run on the older VM.

    I'd suggest we wait and see what the May JSR-14 prototype actually looks like before further discussion of compatibility. Remember that the compatibility-point of the whole JSR-14 proposal was that GJ code could interoperate with 'old code'. (I.e. old code running on new VMs.) This is desirable, still maintained in the JSR-14 implementations (as far as I know), and a completely separate issue than having new code run on old VMs.
  • 843793
    843793 Member Posts: 41,732 Green Ribbon
    You're right -- the latest spec might have some substantial changes in it. But the only changes I've heard of is a change in the javac compiler, not other compilers, not the JVM, and not JSR-14.

    The compatibility of JSR-14 goes far beyond allowing generic code to work with older code. It does so with no changes in the JVM at all. The only JVM changes necessary are to support reflection to get information on generic parameters.
  • brucechapman
    brucechapman Member Posts: 466
    Even the reflection stuff doesn't NEED a new JVM. It does need the new API to be implemented, but that can be done with the current VM.

    I have implemented a set of static methods to simulate the new reflection API, and it works fine on the 1_4_1 VM.

    However, the new reflection stuff can be done more efficiently if the bootstrap class loader can read the generic attributes directly. (I re-read the class file with Apache's BCEL, and look at the attributes that way).

    Bruce
  • 843793
    843793 Member Posts: 41,732 Green Ribbon
    Bruce, Schapel, you seem to have missed what fredastaire just said about some last-minute changes to the type system.

    If I'm guessing right (and I hope I am!), you'll be able to do things like this:

    List<String> names = new String[50]; // arrays are fixed-size Lists, but far faster than ArrayList!
    names.set(0,"fred"); // same as names[0] = "fred"
    names.set(1,"bert");
    Collections.sort(names); // all List operations will now work with arrays, and work at array-like speed!

    This is amazing stuff - no longer will Java have 2 separate systems of collections (arrays versus Collections) and 2 systems of parameterized types (T[] versus, say, Collection<T>).

    No longer will we need the clunky separation between the static functions in the Arrays class and the Collections class, which do mostly the same operations but have to have different implementations.

    The same goes for any function anywhere that is currently passed (or returns) an array or a List - now it will be able to accept either.

    If this needs a new JVM, then I think it's more than worth it.
  • 843793
    843793 Member Posts: 41,732 Green Ribbon
    discussion of compatibility. Remember that the
    compatibility-point of the whole JSR-14 proposal was
    that GJ code could interoperate with 'old code'.
    (I.e. old code running on new VMs.)
    There was more to than that. They also wanted minimal changes in the JVM. Proposals to allow generics to work with primitives, which would also have been compatible with old code, were rejected partly on the grounds that significant changes in the JVM might be required. (Actually I think only modest changes would be required.)

  • 843793
    843793 Member Posts: 41,732 Green Ribbon
    Right, but experience with GJ has shown (and I've over 100,000 lines of it in my project) that the invariant subtyping of parameterized classes is rather too inflexible for many needs. Try coming up with a "correct" type for Collections.unmodifiableCollection(), for example: the closest I could come was
    <A, B extends A> Collection<A> unmodifiableCollection(Collection<B> c) which doesn't actually work with the current JSR-14 type inference algorithm. And if you don't understand why the odd parameterization is necessary, than I'd venture to suggest you haven't used JSR-14 for any large projects.

    A 2002 programming-languages paper seemed to point a novel way around this and similar difficulties, and my understanding is that the JSR-14 committee has embraced the opportunity to innovate and advance the state-of-the-art. This promises to also solve the long-standing type-system hole which required runtime tests at every array store operation for the ArrayStoreException case.

    (Briefly, consider: ((Object[])(new Integer[1]))[0] = "hello"; )

    So my understanding is that the JSR-14 committee has come up with a new unified variance-based type system for both arrays (correcting the type system unsoundness there) and parameterized classes. I don't know if this goes so far as to make arrays and collections fully interoperable, but I certainly consider it not outside the realm of possibility that a new supertype or interface was added to the array class hierarchy to make this work, which would then require VM support. Alternatively, perhaps only the VM's bytecode verifier needed to be tweaked to support the special case of no-check-needed arrays. Who knows?

    It is certainly true that one of the primary advantages of the original GJ proposal was that it required no JVM changes. But at that point Sun was looking at bundling GJ into Java 1.4 within a very short timeframe. The original proposal had other type system issues that forced the delay of JSR-14 (possibly there were more prosaic engineering schedule issues as well), and the longer timeframe of the Java 1.5 release seems to have opened up the opportunity for some small VM changes to better support the spec. My impression is that the engineers are taking time to do this right (i.e. produce an elegant and correct design) rather than just shoving it out the door as quickly as possible. Doing it right seems to include making the few VM changes they feel are helpful and worthwhile.

    All this said, although I've pried a few hints from the Sun engineers, I have only educated guesses about the contents of the next prototype compiler release and such. So don't take my word as gospel. I'm only suggesting here that there may be "good" reasons to trade off some compatibility goals (running on older VMs) for some additional design goals. Until we see the new design, we shouldn't waste too much effort trying to decide whether this tradeoff was wise or not.
  • 843793
    843793 Member Posts: 41,732 Green Ribbon
    We won't sacrifice one iota of compatibility.
This discussion has been closed.