I understand that Java is generally invariant since it does not want to deal with issues of co/contra-variance.
So in general,
List<Parent> a = new ArrayList<Child>();
will require a type-erase-like cast via (List)
to make work.
However,
List<Parent> p = Collections.singletonList(<Child>);
works as is, without a cast, despite claiming to return a List<Child>
via the documentation.
I experimented a bit and found this is a property of generic returns in general, and is not specific to Collections.singletonList
.
There are a couple possibilities here:
- it’s inferring the return type based on what it is being assigned to
- this doesn’t make much sense, since context-free compilation wouldn’t work so well
- a good point to be made is something like
Vector<String> s = new Vector<>();
works like this
- it actually just returns
List
, type-erased, so theList<T>
is a misnomer- this makes sense to me, but it’s strange that this is an exception case for the compiler and not the first assignment I gave as an example
What exactly is going on here, and why is it okay in this scenario, upon a function return with generics, but not with assignment in general?
Taking this one step further, how does Java implement and special-case this?