On Mon, Aug 10, 2009 at 9:00 PM, Marshall Schor<m...@schor.com> 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 :-) >
One other way to look at this - why are Collections any different than methods that return single elements? If I have a method Number getNumber() and I "know" in some situation that the Number is really an Integer, should I be able to call: Integer x = getNumber()? Normally such a thing is not allowed without an explicit cast. And for me at least I just take that for granted as part of what a strongly-typed language does, so it's very bizarre to think of it not doing that. -Adam