Casting Comparator用于子类

时间:2013-02-11 05:06:17

标签: java generics casting

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

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()返回Comparator<? super T>而不是使用downcast(),或者我可以将所有代码更改为不使用或显式检查null Comparators(这也会删除需要使用向下转换),但这些更改似乎都不值得为大型代码库付出努力。是否存在downcast()chainComparators()失败的合理情况?

2 个答案:

答案 0 :(得分: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);
        }
    };
}

答案 1 :(得分:1)

它应该是安全的,因为Comparator是一个使用者,这意味着T的实例只作为参数传递,并且永远不会返回。

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