A small correction: allowing downcasting doesn't generate a warning about unchecked casting.
Here's a small test case in case you want to play with this: package generics; import java.util.List; public class TestG { class Box<T> { // version returning down-castable thing <U extends T> U get() {return null;} <U extends T> List<U> getL() {return null;} } class StrictBox<T> { // version returning just type T T get() {return null;} List<T> getL() {return null;} } Box<Number> box = new Box<Number>(); StrictBox<Number> sbox = new StrictBox<Number>(); void test() { // returning elements Number n = box.get(); // OK Integer n2 = box.get(); // OK Number sn = sbox.get(); // OK Integer sn2 = sbox.get(); // fails Integer sn3 = (Integer) sbox.get(); // OK // returning lists List<Number> ln = box.getL(); // OK List<Integer> ln2 = box.getL(); // OK List<Number> sln = sbox.getL(); // OK List<Integer> sln2 = sbox.getL(): // fails, no fix available } } -Marshall Marshall Schor wrote: > Here's a new thread to discuss just one particular issue - a generics > tradeoff. > > In other posts, people have expressed misgivings about letting users > "downcast" List<someType> to List<someSubType>, if it cannot be > *guaranteed* at compile time that this is valid. > > Here's a simple example, for instance, using two built-in Java classes: > Number > Integer (a subtype of Number) > > If we have a method which returns a List<Number>, and you happen to know > it only contains Integers, and you want to use a for-each on it with a > method that only exists in the Integer class, you have to do manual > casting within the loop. > > An alternative might have been to do: > List<Number> numbers = ...; > List<Integer> int_version = numbers; // not allowed, gives compile error > > So once we're given the "numbers" object, as far as I can see, we're > stuck with its typing. (Please tell me if I'm wrong here). > > I see that there is a trade-off between specifying return types as > specific types, and specifying them as T extends X, and letting the user > specify a possibly incorrect downcast. The tradeoff on the plus side is > that the user gets to write the new style for-each loops, and have code > without casts inside loops, etc., and on the minus side, the user when > doing this gets that warning about the possibility that at runtime a > casting error could be thrown. But of course, that same casting error > could be thrown in restricted style, too, at the point of the explicit > user cast. > > I'll probably stop trying to convince others if they continue to feel > that the tradeoffs here should be in the direction of returning only > specific types (disallowing users from specifying downcasting in that > manner), versus using types of the form T extends X, > which allows users to specify downcasting. > > I'd be interested in any literature pointers discussing this trade-off > issue, if anyone has good ones :-) > > -Marshall > > >