<@U78L28DMX> it all about type safety, which compi...
# tornadofx
a
@amanda.hinchman-dominguez it all about type safety, which compiler can guarantee. Because of inheritance you can do tricky things, i.e. standard covariance array problem:
Copy code
String[] a = ...;
Object[] o = a;
o[i] = 42;
To prevent that all generics are invariant:
Copy code
List<String> s = ...;
List<Object> o = s; // compile error;
but it's very hard constraint. So language introduced the means to explicitly specify co-/contrvariance, which gives flexibility in some typical situations, but it also forbids you certain set of things, like this: covariance gives you ability to read, but you can't insert:
Copy code
List<? extends Number> s = <numbers>;
s.add(<number>);
but you can't
Copy code
s[0] = <number>;
because of the problem mentioned in the first paragraph (i.e.
s
is the list of `double`s and you
add
integer
). covariance gives you upper bound, saying that "there can be any class derived from this class/interface". contrvariance is somewhat opposite. You're free to insert, but you can't read:
Copy code
List<? super Double> s = <numbers>;
s.remove(0);
you can't read, because you know the lower boundary (
Number
), you don't know what kind of other objects might be here (
Double -> Number -> Object
).