Upper bounds werden dort benutzt, wo ich eine Klasse wo ich eine Klasse referenziere, deren Methode ich (nachher) aufrufe und ich definieren möchte, dass diese Methode keine spezifischeren Parameter-Objekte verlangt, als von mir im Lover-Bound angegeben. Z.B. werde ich nur Früchte liefern, also soll die Methode keine Orangen verlangen.
List<? super Frucht> fruchtListe;
Siehe hierzu Lower Bounds – Wozu?
<?>, <? super …> dürfen nicht in der Typparameter-Sektion einer Generischen Klasse verwendet werden. Folgendes geht nicht:
public class GenerischeKlasse<?> //falsch!
public class GenerischeKlasse<? super Number> //falsch!
Der Lower Bound bezeichnet die Restriktion der aktuellen Parametrisierung der Generischen Klasse. Er bezeichnet NICHT die upper Bound des danach dieser Klasse in irgendeiner Methode übergebenen Parameters:
public class UpperBound1 { public static void main(String[] args) { List<? super Number> list = new ArrayList<Number>(); //Folgendes geht selbstverständlich, weil: // List<? super Number> sagt aus, dass <T> in // :List.add(T value) mit Number oder etwas unspezifischerem // aktuell parametrisiert sein muss sein muss. //Es darf also z.B. sein: // List<Object> mit Methode add(Object value) oder // List<Number> mit Methode add(Number value) // Und: add(Object v) und add(Number v) haben keine Problem mit Integer als Parameter list.add(Integer.valueOf("89")); //Achtung beim Retrieval von Werten aus "? super" referenzierten Objekten: // //Integer i = list.get(0); //Incompatible types: Integer i = (Integer) list.get(0); //Riskant!! Object o = list.get(0); } }