3

在实践中,执行以下操作是否安全?

public static <T> Comparator<T> downcast(final Comparator<? super T> orig) {
    @SuppressWarnings("unchecked")
    Comparator<T> casted = (Comparator<T>) orig;
    return casted;
}

这是一个人为的用法示例:

public static <T> Comparator<T> chainComparators(final Comparator<? super T> a,
        final Comparator<? super T> b) {
    if (a == null) {
        return downcast(b);
    }
    if (b == null) {
        return downcast(a);
    }
    return new Comparator<T>() {
        @Override
        public int compare(T o1, T o2) {
            int i = a.compare(o1, o2);
            if (i == 0) {
                i = b.compare(o1, o2);
            }
            return i;
        }
    };
}

public static Comparator<Integer> ODD_FIRST_COMPARATOR = new Comparator<Integer>() {
    @Override
    public int compare(Integer i1, Integer i2) {
        boolean isEven1 = (i1.intValue() % 2) == 0;
        boolean isEven2 = (i2.intValue() % 2) == 0;
        return Boolean.compare(isEven1, isEven2);
    }
};

public static Comparator<Number> ABS_NUMBER_COMPARATOR = new Comparator<Number>() {
    @Override
    public int compare(Number n1, Number n2) {
        double d1 = Math.abs(n1.doubleValue());
        double d2 = Math.abs(n2.doubleValue());
        return Double.compare(d1, d2);
    }
};

public static void main(String[] args) {
    Comparator<Integer> comp = null;
    comp = chainComparators(comp, ODD_FIRST_COMPARATOR);
    comp = chainComparators(comp, ABS_NUMBER_COMPARATOR);

    List<Integer> list = new ArrayList<Integer>();
    list.add(-42);
    list.add(-23);
    list.add(-15);
    list.add(-4);
    list.add(8);
    list.add(16);

    Collections.sort(list, comp);
    System.out.println(list); // prints [-15, -23, -4, 8, 16, -42]
}

我知道我可以chainComparators()returnComparator<? super T>而不是 using downcast(),或者我可以将所有代码更改为不使用或显式检查 null 比较器(这也消除了使用向下转换的需要),但这些更改似乎都不值得为庞大的代码库。downcast()是否存在任何一种或chainComparators()将失败的合理情况?

4

2 回答 2

3

如果您不想要未经检查的警告,您可以随时这样做:

public static <T> Comparator<T> downcast(final Comparator<? super T> orig) {
    return new Comparator<T>() {
        @Override
        public int compare(T o1, T o2) {
            return orig.compare(o1, o2);
        }
    };
}
于 2013-02-11T06:57:33.680 回答
1

它应该是安全的,因为Comparator它是一个消费者,这意味着 的实例T仅作为参数传递,并且从不返回。

据我所知,您的代码很好。

于 2013-02-11T05:55:41.500 回答