¿Cómo se usaría la contravarianza en los genéricos de Java?
En Java, la covarianza permite que el diseñador de API especifique que una instancia puede generalizarse como un determinado tipo o cualquiera de los subtipos de ese tipo. Por ejemplo:
List<? extends Shape> shapes = new ArrayList<Circle>();
// where type Circle extends Shape
La contravarianza es al revés. Nos permite especificar que una instancia puede generalizarse como un cierto tipo o supertipo.
List<? super Shape> shapes = new ArrayList<Geometry>();
// where Shape extends Geometry
¿Cómo es útil la contravarianza de genéricos de Java? ¿Cuándo elegirías usarlo?