maks
maks

Reputation: 6006

Using casting in generics in return statement

I have the following classes:

public class Base {
   public int someMethod(){...}
}

public class Derrived extends Base {
   @Override
   public int someMethod(){...}
}

Also I have a method that return the List<Base>

List<Base> method() {
   return fetch();
}

Method fetch() returns List<? extends Base> but actually it holds list of instances of Derrived class

List<? extends Base> fetch() {}

But code that defines method method() will not compile. It requires casting to List<Base>. Why I need cast it if I always can treat to instances of that collection as instances of Base class?

Upvotes: 1

Views: 573

Answers (2)

pcalcao
pcalcao

Reputation: 15990

You cannot do this because there is no guarantee that someone wouldn't try to insert into the Collection an object of a different sub-class of Base.

What would happen then?

It would look ok, but you're basically trying to use two different types of objects in the same collection, something that, as you know, is not allowed.

Upvotes: 1

Jon Skeet
Jon Skeet

Reputation: 1500175

A List<? extends Base> isn't the same thing as a List<Base>, in the same way that a bunch of bananas isn't a fruitbowl.

Consider:

List<Derived> x = new ArrayList<Derived>();

// This is valid...
List<? extends Base> y = x;

// This is what you *want* to be valid
List<Base> z = y;

z.add(new Base());

// This looks fine at compile-time... but what would you expect it to do?
Derived d = x.get(0);

It's one thing to treat all existing elements of a List<Derived> as instances of Base - but you can't add a Base to a List<Base>, whereas you can add one to a List<Derived>. There not every List<Derived> is List<Base>.

Upvotes: 6

Related Questions