This post originated from an RSS feed registered with Java Buzz
by Avery Regier.
Original Post: JavaOne Updates on the new language features.
Feed Title: cAVEman's Musings
Feed URL: http://sedoparking.com/search/registrar.php?domain=®istrar=sedopark
Feed Description: Musings of Avery Regier on the subject of Java, DevWiki, J2EE, Java operating systems, and whatever else strikes my fancy.
I was at the BOF last night for how the new language features will be affecting the libraries. Here's a little of what I've learned.
Resolving Variable Arguments
It looks like there are two simple rules that will make resolving varargs methods.
Resolve everything normally first.
Resolve to the most specific method.
Generics aren't so simple as we thought.
When you start looking at how the Collections Frameworks implement generics, you start seeing how complex this will all be for library writers (like me). Here's a test: Is the following valid?
public interface Collection<T> {
public void addAll(Collection<T> collection);
public void add(<T> o);
}
public class Foo {}
public class Bar extends Foo {}
Collection<Foo> foos = new ArrayList<Foo>();
foos.add(new Foo());
foos.add(new Bar());
Collection<Bar> bars = new ArrayList<Bar>();
bars.add(new Bar());
foos.addAll(bars);
Answer: Nope! So what is the issue?
It isn't adding a new Bar() to foos because for
public void add(<T> o);, <T> includes subtypes. The problem comes with public void addAll(Collection<T> collection); Here, Collection<Foo> is not inclusive of Collection<Bar>. It's not exactly intuitive that this limitation exists.
This fixes it:
public interface Collection<T> {
public void addAll(Collection<? extends T> collection);
public void add(<T> o);
}
This means that a Collection of objects of any class that extends T. <T extends ?> would mean for Bar, Object, Foo, or Bar, or for Foo, only Object or Foo. Basically, the ? is placed where it would be in a class definition. When I first read this, I thought the semantics should be the opposite of this. This syntax is not exactly terse. The syntax of this is definitely subject to change, and hopefully it will. If you have any ideas that would be easily read and written, I'm sure the JSR folks would love to hear it right now.
By the way, you're probably wondering like I did what you'd ever use <T extends ?> for. Here's the main use case: Comparators. A comparator of Foos is valid for Bars, but a comparator of Bars isn't valid for Foos. Wrap your mind around these for a little while, and you'll see why just simple generics syntax isn't good enough.
I just wish <T> always included the subtypes unless specifically noted otherwise (with maybe something like <*T>, which is nice and terse.)