1

Why can I not assign an ArrayList<ArrayList<Integer>> into an ArrayList<List<Integer>> like below:

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

Aren't all ArrayLists Lists and therefore where I can put a List, I can also place an ArrayList?

Abundance
  • 1,963
  • 3
  • 24
  • 46

2 Answers2

1

If this were legal, you could do the following:

ArrayList<ArrayList<Integer>> y = new ArrayList<>();
ArrayList<List<Integer>> x = y;  // Compiler error! Pretend it's OK, though.

x.add(new LinkedList<>());  // Fine, because a LinkedList<Integer> is a List<Integer>

but then this would fail:

ArrayList<Integer> a = y.get(0);  // ClassCastException!

because the first element of y is a LinkedList, not an ArrayList.

You can assign y to x if the type of x is

ArrayList<? extends List<Integer>>`

because you couldn't then add anything (other than literal null) to that list, hence the ClassCastException wouldn't occur.

Andy Turner
  • 137,514
  • 11
  • 162
  • 243
0

Because if x is typed as an ArrayList<List<Integer>>, then you can stuff any kind of list into x, so this should be legal:

x.add(new LinkedList<Integer>());

But if x is actually an ArrayList<ArrayList<Integer>>, that shouldn't be allowed.

This is allowed:

ArrayList<? extends List<Integer>> x = new ArrayList<ArrayList<Integer>>();

But with that definition of x, you won't be able to actually put anything into x.

Daniel Martin
  • 23,083
  • 6
  • 50
  • 70