Monday, April 8, 2019

Generics and collections

this one has no compilation errors:

Set a;
Set<Object> b;
Set<? super Object> c;

a = new HashSet();
b = new HashSet<>();
c = new HashSet<>();

c = a;
c = b;
b = a;
b = c;
a = c;
a = b;



but if I use

Set<Object> b;
Set<?> c;

then "c = b" gives compilation error

Error:(26, 13) java: incompatible types: java.util.Set cannot be converted to java.util.Set


This is interesting, since ? means "any Object and subclasses"... while "? super Object" means "Object and its superclasses"
but Object has no superclasses, so effectively it's only Object.


If I use:
b = new HashSet<>();
Set<?? extends Object> c;

then
b = c;
fails with the same error:

Error:(26, 13) java: incompatible types: java.util.Set cannot be converted to java.util.Set


The raw type a can be assigned all the time to all the others.


similarly, collections are INVARIANT:
Set<Number> numset = new HashSet<>();
Set<Integer> intset = new HashSet<>();
Set<?> allset = new HashSet<>();

numset = intset; // INVALID
intset = numset; // INVALID
allset = numset; // VALID
numset = allset; // INVALID



but arrays are COVARIANT:

Number[] numarr = new Number[1];
Integer[] intarr = new Integer[1];
numarr = intarr; // VALID
intarr = numarr; // INVALID










No comments: