0
List<Object> a = null;
List<?> b = null;
b = a; // Can be assigned

List<List<Object>> a = null;
List<List<?>> b = null;
b = a; // Cannot be assigned

Could you explain why Java does not allow the second case? What are the side-effects of the case and underlying philosophy?

I have seen Is List<Dog> a subclass of List<Animal>? Why are Java generics not implicitly polymorphic? but this question is different because there is the inheritance relationship between Dog and Animal but here is no relationship between the wildcard type ? and Object. Wildcard type represents 'some unknown type,' which means List<?> can be List<Object> in the runtime: Intuitively speaking, here List<?> is a candidate Dog (Not Animal), there List<Object> is a Dog.

List<String> cannot be assigned to List<Object>, which is the same case of the previous question and explained there why it is not allowed. However, List<String> can be assigned to List<?>, which is the case I am asking and different from the previous case. Since the assignment is allowed, I expected List<List<Object>> can be assigned to List<List<?>>.

user16217248
  • 3,119
  • 19
  • 19
  • 37
freddy
  • 463
  • 1
  • 8
  • 20
  • 3
    See the duplicate. `List` is the `Dog` here, and `List>` is the `Animal`. You probably want to use `List extends List>>` as the type of `b`. – Sweeper Jul 19 '23 at 03:14
  • 1
    Suppose you did `b.add(0, new ArrayList())` and then `a.get(0).add("uh oh")`. Now you have heap pollution. – shmosel Jul 19 '23 at 03:58
  • @Sweeper `List>` can be any `List`, which means `List>` can be `List`. Is this same problem? I am not sure about that. I think wildcard should be treated differently. Am I wrong? please let me know.. – freddy Jul 19 '23 at 06:28
  • `Animal` can be any subclass of `Animal`, which can be `Dog`. The subtyping relationships are basically the same. – Sweeper Jul 19 '23 at 06:37
  • @Sweeper Can you let me know which type can be assigned to variable `b` in the example? Based on your explanation, I think there is no type that can be assigned to `b` except itself. Am I right? – freddy Jul 19 '23 at 06:47
  • Well the type argument has to be `List>`, but you can do `ArrayList>` for example. – Sweeper Jul 19 '23 at 06:49
  • @Sweeper `List> b = new ArrayList<>(); List c = new ArrayList<>(); List d = new ArrayList<>(); b.add(c); b.add(d);` works but `b = a` does not work, which confuses me a lot. Although after I define `List> b`, `c` and `d` still can be added to `b` but not `b=a`. Hmm.... I have to think about it more... thank you for your answers – freddy Jul 19 '23 at 07:08
  • See @Sweeper 's first comment: `List` is the `Dog` and `List>` is the `Animal`. `Dog` can be assigned to `Animal`, but that doesn't mean that a `List` can be assigned to a `List`. A `List>` can't be assigned to a `List>` for exactly the same reason. – tgdavies Jul 26 '23 at 05:47

0 Answers0