有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java 8 lambda泛型比较器编译器警告

此lambda表达式用于比较两个对象:

private static final Comparator NATURAL_ORDER_COMPARATOR1 = 
        (Comparator) (final Object o1, final Object o2) -> ((Comparable) o1).compareTo(o2);

生成此编译警告:

warning: [unchecked] unchecked call to compareTo(T) as a member of the raw type Comparable
(Comparator) (final Object o1, final Object o2) -> ((Comparable) o1).compareTo(o2);
where T is a type-variable:
T extends Object declared in interface Comparable

此lambda表达式用于比较两个T对象:

private final Comparator<T> NATURAL_ORDER_COMPARATOR2 = 
        (Comparator<T>) (final T o1, final T o2) -> ((Comparable<T>) o1).compareTo(o2);

生成此编译警告:

warning: [unchecked] unchecked cast
(Comparator<T>) (final T o1, final T o2) -> ((Comparable<T>) o1).compareTo(o2);
required: Comparable<T>
found:    T
where T is a type-variable:
T extends Object declared in class Tree01

非常感谢您的决议和解释/评论


共 (1) 个答案

  1. # 1 楼答案

    不能定义可以比较任意ComparableComparator,因为不能将StringInteger进行比较,尽管两者都实现了Comparable。您需要一个类型变量来表示Comparator.compare方法的两个参数必须兼容以进行比较的约束

    但是不可能使用字段定义这样的泛型Comparator,因为在声明字段时不能引入类型参数。它仅使用工厂方法工作:

    public static <T extends Comparable<? super T>> Comparator<T> naturalOrder() {
        return (a,b) -> a.compareTo(b);
    }
    

    public static <T extends Comparable<? super T>> Comparator<T> naturalOrder() {
        return Comparable::compareTo;
    }
    

    你可以像这样使用它

    Comparator<Integer> ci = naturalOrder();
    Comparator<String> cs  = naturalOrder();
    // in the current version of Oracle's JRE/OpenJDK this will print true
    System.out.println(ci==(Object)cs);
    

    这表明,使用给定的JRE,它产生一个单实例,与性能中存储在字段中的比较器相当。但是从泛型的角度来看,它们有不兼容的类型,这使得不可能定义一个包含该比较器并同时与IntegerString兼容的单一变量

    无法声明具有类型参数的字段是Collections.EMPTY_LIST在引入泛型时得到Collections.emptyList()补充的原因,也是新方法^{}与您尝试的目的相同,是一个方法而不是字段的原因