2013-02-11 67 views
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] 
} 

我知道我可以做的,而不是使用downcast()chainComparators()回報Comparator<? super T>,或者我可以改變所有的代碼不使用或顯式檢查空比較器(這也消除了使用向下轉換的需要),但這些更改似乎都不值得爲大代碼庫付出努力。有沒有合理的情況下downcast()chainComparators()會失敗?

回答

1

它應該是安全的,因爲Comparator是一個消費者,這意味着T的實例僅作爲參數傳遞,並且從不返回。

據我所見,你的代碼是好的。

+0

我想盡可能多。謝謝。 – blurredd 2013-02-14 02:34:36

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); 
     } 
    }; 
}