Como a contravariância seria usada nos genéricos Java?
Em Java, a covariância permite que o designer da API especifique que uma instância pode ser generalizada como um determinado tipo ou qualquer um dos subtipos desse tipo. Por exemplo:
List<? extends Shape> shapes = new ArrayList<Circle>();
// where type Circle extends Shape
Contravariância vai para o outro lado. Ele nos permite especificar que uma instância pode ser generalizada como um determinado tipo ou supertipo.
List<? super Shape> shapes = new ArrayList<Geometry>();
// where Shape extends Geometry
Como a contravariância do Java generic é útil? Quando você escolheria usá-lo?