【发布时间】:2020-12-02 06:38:57
【问题描述】:
最近我在 Java Comparator 类中偶然发现了以下代码:
public static <T, U extends Comparable<? super U>> Comparator<T> comparing(
Function<? super T, ? extends U> keyExtractor)
{
Objects.requireNonNull(keyExtractor);
return (Comparator<T> & Serializable)
(c1, c2) -> keyExtractor.apply(c1).compareTo(keyExtractor.apply(c2));
}
让我感到困惑的是(Comparator<T> & Serializable) 部分。由于该方法只返回一个比较器,我看不到转换为可序列化的用途。我也没有看到以这种方式投射任何东西的理由,还是我错过了什么?
在我看来,如果我想将一个 Object 转换为多种可能的类型,我可以像这样引入另一种泛型类型:
public static <T, U extends Comparable<? super U>, V extends Comparator<T> & Serializable>
V comparing(Function<? super T, ? extends U> keyExtractor)
{
Objects.requireNonNull(keyExtractor);
return (V) (c1, c2) -> keyExtractor.apply(c1).compareTo(keyExtractor.apply(c2));
}
这样可以将返回的值分配给 Comparator 或 Serializable 变量。
我能想到的唯一其他原因是将这种转换用作某种类型检查,以查看 lambda 表达式是否实际上返回了 Serializable。
如果你们中的任何人对这种类型的演员有经验或知道这样的演员可以完成什么,我们将不胜感激。
【问题讨论】:
-
您不能以您发布的方式将类型变量
V声明为返回类型。这就像承诺“调用者想要返回的任何类型,我都会做(只要该类型是Comparator<T>和Serializable的子类型)”。您不能返回未知的调用者选择的类型。
标签: java generics lambda casting ampersand