Warum verwenden die Factory-Factory-Methoden häufig einen spezifischen generischen Parameter (wie T
) anstelle eines beschränkten Wildcard-Parameters (wie ? super T
)?In Guava, warum wird nur "T" verwendet, wo "Super T" möglich wäre?
Zum Beispiel die Unterschrift von Functions#forPredicate ist:
public static <T> Function<T, Boolean> forPredicate(Predicate<T> predicate)
Warum nicht:
public static <T> Function<T, Boolean> forPredicate(Predicate<? super T> predicate)
Welche wäre so etwas wie die folgenden möglich machen?
Predicate<Number> isPositivePredicate = ...
Function<Integer, Boolean> isPositiveInteger = Functions.forPredicate(isPositivePredicate);
// above line is compiler error:
// Type mismatch: cannot convert from Function<Number,Boolean> to Function<Integer,Boolean>
Ist es, weil Verbraucher von Function
und Predicate
zu erwarten sind, die notwendigen beschränkten Wildcard Parameter haben, um diese überflüssig zu machen? Zum Beispiel würden die allgemeinen Grenzen für Iterables#find erlauben eine Predicate<Number>
zu auf einem Iterable<Integer>
verwendet werden:
public static <T> T find(Iterable<T> iterable,
Predicate<? super T> predicate)
Gibt es andere Gründe?
re. Der erste Punkt drängt den Verbraucher nicht einfach dazu, zu werfen, was das Schlimmste von zwei Übeln ist? Auch neugierig, wenn du "wir" sagst, meinst du, du hast dich auf diese oder nur die Software-Community im Allgemeinen entwickelt. – djechlin
Genauer gesagt - wie hat sich diese Politik in der Praxis bezahlt gemacht? Derzeit die einzigen Situationen, in denen ich es mir vorstellen kann, würde der Verbraucher nur mit Casting zu abgeleiteten Typ umgehen. – djechlin
Wenn ich "wir" sage, meine ich, dass ich im Google Java Core Libraries Team bin, das Guava entwickelt. Aber der Konsument sollte nie zu casten haben: Ein 'Prädikat super T>' kann immer direkt verwendet werden, wo immer Sie ein 'Prädikat' verwenden würden. Es gibt keine Notwendigkeit zu casten; Sie können auf genau die gleichen Werte angewendet werden. –