2

I got a little bit confused the other day when it comes to generics and covariance/contravariance. I know C# specifies covariant/contravariant type parameters, but is there really a similar concept in Java?

I understand you can declare:

List<? extends String> l = ...
List<? super String> l2 =...

and now l can take list of MyString, add method is not allowed etc. while l2 can take List<Object> and add String to it, but cannot get any element, as described here Covariance- contravariance in Java. This, however, is simply declaring a List with a type parameter that accepts subtyes/supertypes, not doing "proper" covariance like:

Iterable<Animal> a = new Iterable<Dog>();

Am I confused or does Java simply not support proper covariance definitions? Thanks.

Community
  • 1
  • 1
Bober02
  • 15,034
  • 31
  • 92
  • 178

1 Answers1

-2

Java's type variance is at the use site, not at the declaration site. Say we have a type declaration

interface List<E>

we can use it covariantly (in original syntax)

List<+Animal> animals = new ArrayList<Dog>();

the + annotation on the type variable makes the parameterized type covariant.

That is not bad at all. We can have contraviant List<-Animal> too. It is more flexible.

UNFORTUNATELY, Java designers overestimated the stupidity of Java programmers, they think the single letter symbol +/- will drive us mad; that we must see english words to understand what's going on. And it was still the time in Java that verbosity is to be celebrated. So we get this syntax

List<? extends Animal>

I think it is absolutely retarded.

irreputable
  • 44,725
  • 9
  • 65
  • 93