Reputation: 569
I don't really know how to explain the problem I have. Below is an example of a few objects I have.
Lets say I have classes
public class Foo{}
public class FooBar extends Foo{}
All of that is fine, however if I take a list and say I want it to be full of Foo
objects, I cannot provide it a FooBar
object. Why is this?
Example:
List<Foo> fooList = Arrays.asList(new FooBar());
If FooBar extends Foo
, why cant it be cast back to Foo
?
Upvotes: 3
Views: 93
Reputation: 124235
As already mentioned in comments Arrays.asList(T...)
returns List<T>
. Since you passed FooBar
instance to that method type inference from Java 7 used FooBar
type as T
representation which means that this method returns List<FooBar>
which can't be assigned to List<Foo>
(you can read more about it at: Is List<Dog> a subclass of List<Animal>? Why aren't Java's generics implicitly polymorphic?)
In Java 8 type inference was improved to make lambdas more useful. Now T
infers type not only from parameters, but also from target - reference variable which should hold result. This allows T
to infer Foo
from List<Foo> fooList
rather than new FooBar()
argument.
To solve this problem in earlier versions like in your case Java 7 you can explicitly set generic type for generic method asList
like
List<Foo> fooList = Arrays.<Foo>asList(new FooBar());
// ^^^^^ -- set generic types before method name
More info at: https://docs.oracle.com/javase/tutorial/java/generics/genTypeInference.html (especially "Target Types" section)
Upvotes: 5
Reputation: 8695
Arrays.asList(new FooBar())
returns a List<FooBar>
, which cannot be assigned to a List<Foo>
. If it could be assigned to that, then you could create a List<FooBar>
, assign it to a List<Foo>
, and then add Foo
to a list that must contain FooBar
, which is clearly an error.
Instead, you need:
List<Foo> fooList = new ArrayList<>();
fooList.add(new FooBar());
Upvotes: 3