participate


Generics - What's changed in the 1.2 prototype.
<<   Back to Forum  |   Give us Feedback
6 Duke Stars available
This topic has 8 replies on 1 page.
fredastaire
Posts:97
Registered: 1/3/00
What's changed in the 1.2 prototype.   
Mar 21, 2002 2:28 AM

 
The 1.2 prototype has surprisingly little documentation. I started this thread to try to remedy that, in part. I'm going to start off by listing what's I've noticed changed in 1.2, gotchas to watch out for, etc, and I hope you all will follow up below w/ all the rest of the changed things which I haven't discovered yet.

1) THE COMMAND-LINE scripts/javac TOOL NEEDS THE '-gj' OPTION.
The previous release didn't. This is a big user-noticible change if you were using the older 1.0-ea prototype in makefiles and such. Note that the 'javac --help' information lists '-gj' as the default; it is wrong. '-nogj' is the default. I hope this doesn't reflect on the status of GJ in java 1.5?

2) THE COLLECTIONS API HAS CHANGED.
This is made more interesting by the fact that this release doesn't come with any javadoc and (as far as I know) javap still crashes when given GJ .class files. The only way to tell that the interface
has changed out from under you is the javac error message which you will sometimes get when you try to extend a Collection class
with a now-incorrectly-typed method. (Other times, javac will just crash.)

The changes I have seen have altered the signature of addAll, putAll, and similar methods from:
class Collection<V> {
   boolean addAll(Collection<V> c);
}

to
class Collection<V> {
   <T extends V> boolean addAll(Collection<T> c);
}


Note that this gives you much more flexibility and restores covariance in some ways; but it also breaks all your Collection subclasses which override methods with the now-obsolete signatures.

Are there any other similar method changes to watch out for? Post below; if the 'offical' javadoc for this 1.2 prototype release isn't forthcoming 'soon' I'll probably hand-edit the 1.0 prototype javadoc to be correct for the new release and post it on the web for everyone to use pro tem. (But it would be nice if the Sun folk did this themselves, so I wouldn't have to bother, hint, hint!)

3) NO MORE JAVADOC. Mentioned above; hope you've got a copy of the 1.0 javadoc lying around still.

4) BUGS FIXED. As pnkfelix noted in another post here, some type-system loopholes have been fixed in this release. Also, the bugs which prevented casts from Set to Collection and from Set to Set<T> appear to have been fixed. The bad-line-numbers-on-non-Unix-platforms bug is reputedly gone. Further, it seems that this release compiles non-GJ code better. I'll probably post more on these issues as I get a little more experience w/ this new release. Does anyone else have 'favorite' 1.0-prototype bugs which were fixed in this release?

5) ONLY WORKS ON JDK1.4. The last release didn't work on 1.3 either, as far as I can tell. But, regardless, this is the only documented change in this release (according to the CHANGES file in the distribution).

OK. This feels incomplete. Post below and let's hear what else you've noticed has changed.

[[[ObObscurePersonalNote: Felix, FLEX now has a GJ port. 'magic-4-0' These prototype compilers are far too buggy for me to release it on the rest of the group, but I've been playing with it on my own personal branch.]]]
 
schapel
Posts:2,586
Registered: 6/22/99
Re: What's changed in the 1.2 prototype.      
Mar 21, 2002 8:45 AM (reply 1 of 8)  (In reply to original post )

 
3) The Javadocs were not part of the prototype implementation. They are part of the specification and are still available here: http://jcp.org/aboutJava/communityprocess/review/jsr014/index.html
However, they have not been updated to reflect changes in the API.

6) ThreadLocal and the reference classes (java.lang.ref.Reference, SoftReference, WeakReference, and PhantomReference) are now generic so you don't have to cast the reference returned from the get() methods and the argument to the set method of ThreadLocal is typechecked.
 
joerg.wassmer
Posts:35
Registered: 2/23/98
Re: What's changed in the 1.2 prototype.   
Mar 21, 2002 8:47 AM (reply 2 of 8)  (In reply to original post )

 
With Collection<E> it shouldn't matter if you write
boolean addAll(Collection<E> source)
or
<T extends E> boolean addAll(Collection<T> source)
because both reads as "source elements have to be instance of E".
Both cases compiled successfully for me.
 
schapel
Posts:2,586
Registered: 6/22/99
Re: What's changed in the 1.2 prototype.   
Mar 21, 2002 10:18 AM (reply 3 of 8)  (In reply to #2 )

 
With Collection<E> it shouldn't matter if you write
boolean addAll(Collection<E> source)
or
<T extends E> boolean addAll(Collection<T> source)
because both reads as "source elements have to be
instance of E".

It does matter. Consider the following code:
List<Number> ln = new List<Number>();
TreeSet<Integer> tsi = new TreeSet<Integer>();
ln.addAll(tsi);

With the first way of defining addAll above, this code will not compile. With the second, it will!

The reason is that C<T> does not extend C<S> if S and T are different types. That is, generic types are invariant.
 
fredastaire
Posts:97
Registered: 1/3/00
Re: What's changed in the 1.2 prototype.   
Mar 21, 2002 11:08 AM (reply 4 of 8)  (In reply to #2 )

 
schapel raises a good point. But my immediate concern was the existing code I had where I extended AbstractCollection or the Collection interface (Set, Map, etc). The type signature does matter, and the compiler will not accept your code has valid unless you match the superclass' method signatures exactly (otherwise there are two methods which 'erase to the same signature', which is an error).

So this change breaks existing code you may have written using the first prototype compiler. Which isn't a big deal (it's a prototype, right) but I would have preferred to be told about it in the release notes. =)
 
schapel
Posts:2,586
Registered: 6/22/99
Re: What's changed in the 1.2 prototype.      
Mar 22, 2002 7:35 AM (reply 5 of 8)  (In reply to #4 )

 
I almost forgot:

7) The scripts directory now has a batch file for invoking the compiler on Windows.
On Windows 95/98/Me you must replace the %* at the end of the line with:
%1 %2 %3 %4 %5 %6 %7 %8 %9
It's not pretty, but it works.
 
eliasen
Posts:78
Registered: 3/25/98
Re: What's changed in the 1.2 prototype.   
Mar 22, 2002 8:39 PM (reply 6 of 8)  (In reply to original post )

 
1) THE COMMAND-LINE scripts/javac TOOL NEEDS THE '-gj'
OPTION.

Thanks for noting this. It may have saved me a lot of time. With only this change, my "Frink" project
( http://futureboy.homeip.net/frinkdocs/ , 194 classes with a mix of generic and non-generic code, 25000 lines) recompiled with the new compiler with zero changes. Of course, in the course of building this project, I worked around some bugs in the old compiler.

I think that inner classes still don't work as expected. I don't know if this is a bug, but it's a shortcoming. For example, the following code still doesn't compile:

public class Outer<T>
{
   private T outerMember;
 
   public Outer()
   {
      outerMember = null;
   }
   
   private class Inner<T>
   {
      private T innerMember;
         
      public Inner()
      {
         innerMember = outerMember;
      }
   }
}


The compilation error is:

Outer.java:16: incompatible types
found : T
required: T
innerMember = outerMember;
^
1 error


This isn't a particularly wonderful sample, but often you do want inner classes to be able to access data from the enclosing class (say, the inner class is an enumerator that enumerates over the contents of the outer class.) But you can't. Dang.

If nothing else, a better error message should be produced. To me, "T" sure looks like "T".

The "README" file indicates that the compiled code only works with a 1.3 or later runtime. I've tested with 1.2 and (thankfully) found no cases where it doesn't work (but there may be some.) That would be a showstopper, as many people who use Frink haven't even installed 1.3 yet, and I've worked hard to make it compatible with 1.2, 1.3, and 1.4.

Does anyone know why the documents say that the compiled code only works with a 1.3 environment? Let's hope it's a mistake. I thought one of the goals of the generic compiler was to create bytecode that could run in any JVM. And compiling with the new compiler shouldn't introduce dependencies on classes that the programmer doesn't reference...

I do compile with the -target 1.1 flag for maximum backward compatibility.

3) NO MORE JAVADOC. Mentioned above; hope you've got
a copy of the 1.0 javadoc lying around still.

Gafter's recent comments in this forum indicated that they've not even begun making a version of the javadoc tool that works on generic code. I sorta wished that something magical might have happened since then, but I guess not.

The bad-line-numbers-on-non-Unix-platforms bug is
reputedly gone.

But Java is write-once-run-anywhere! That's impossible! :) Gafter posted a (one-line) patch for the original compiler to this forum just a week ago. Wish I had it a year ago. That's why I wish that releases would be made more often--it was fixed long ago.

5) ONLY WORKS ON JDK1.4. The last release didn't work
on 1.3 either, as far as I can tell.

I tried compiling with 1.3 and the new generic compiler, and got this message:

Exception in thread "main" java.lang.NoClassDefFoundError
at com.sun.tools.javac.v8.Main.bugMessage(Main.java:490)
at com.sun.tools.javac.v8.Main.compile(Main.java:477)
at com.sun.tools.javac.Main.compile(Main.java:36)
at com.sun.tools.javac.Main.main(Main.java:27)

The old compiler did usually work with 1.3 (I've used it for about 10 months with 1.3,) except for 4 classes out of 194, which tickled part of the compiler which used the CharSequence class (which wasn't available until 1.4). Luckily, these 4 classes of mine didn't contain generic code and could be compiled with the normal compiler.

* The new batch file for Windows contains UNIX-style linefeeds. I think that's sorta bad form.
 
joerg.wassmer
Posts:35
Registered: 2/23/98
Re: What's changed in the 1.2 prototype.   
Mar 23, 2002 5:36 AM (reply 7 of 8)  (In reply to #6 )

 
1) >
public class Outer<T>
{
private T outerMember;
 
public Outer()
{
outerMember = null;
}
 
private class Inner<T>
{
private T innerMember;
 
public Inner()
{
innerMember = outerMember;
}
}
}


The compilation error is:

Outer.java:16: incompatible types
found : T
required: T
innerMember = outerMember;
^
1 error


You can write
class Outer<T>
{
   T outer;
 
   class Inner  // here is the difference
   {
       T inner;
   
        Inner()
        {
             inner = outer;
        }
 
   }
}



Unfortunately this doesn't works for subclasses of
the inner class.
 
fredastaire
Posts:97
Registered: 1/3/00
Re: What's changed in the 1.2 prototype.   
Mar 27, 2002 4:00 PM (reply 8 of 8)  (In reply to original post )

 
Updated javadoc for the 1.2 prototype is now at
http://www.cag.lcs.mit.edu/~cananian/Projects/GJ/
along with a javap tool and a list of bugs I've found.
Enjoy!
 
This topic has 8 replies on 1 page.
Back to Forum
 
Read the Developer Forums Code of Conduct

Click to email this message Email this Topic

Edit this Topic
  
 
 
Forums Statistics
    Users Online : 26
  • Guests : 129

About Sun forums
  • Sun Forums is a large collection of user generated discussions. It is here to help you ask questions, find answers, and participate in discussions.

    Check out our guide on Getting started with Sun Forums for a full walkthrough of how to best leverage the benefits of this community.

Powered by Jive Forums