2012-06-08 47 views
6

我寫了一個實用工具方法的Java:的Java6,番石榴,泛型類型推斷

public static final ImmutableSortedSet<TimeUnit> REVERSED_TIMEUNITS = ImmutableSortedSet.copyOf(
     Collections.<TimeUnit>reverseOrder(), 
     EnumSet.allOf(TimeUnit.class) 
); 


/** 
* Get the number of ..., minutes, seconds and milliseconds 
* 
* You can specify a max unit so that you don't get days for exemple 
* and can get more than 24 hours if you want to display the result in hours 
* 
* The lowest unit is milliseconds 
* @param millies 
* @param maxTimeUnit 
* @return the result map with the higher unit first 
*/ 
public static Map<TimeUnit,Long> getCascadingDateDiff(long millies,TimeUnit maxTimeUnit) { 
    if (maxTimeUnit == null) { 
     maxTimeUnit = TimeUnit.DAYS; 
    } 
    Map<TimeUnit,Long> map = new TreeMap<TimeUnit,Long>(Collections.<TimeUnit>reverseOrder()); 
    long restInMillies = millies; 
    Iterable<TimeUnit> forUnits = REVERSED_TIMEUNITS.subSet(maxTimeUnit,TimeUnit.MICROSECONDS); // micros not included 
    // compute the number of days, then number of hours, then minutes... 
    for (TimeUnit timeUnit : forUnits) { 
     long numberForUnit = timeUnit.convert(restInMillies,TimeUnit.MILLISECONDS); 
     map.put(timeUnit,numberForUnit); 
     restInMillies = restInMillies - timeUnit.toMillis(numberForUnit); 
    } 
    return map; 
} 

它適用於:

Map<TimeUnit,Long> map = new TreeMap<TimeUnit,Long>(Collections.reverseOrder()); 

但我第一次

Map<TimeUnit,Long> map = Maps.newTreeMap(Collections.reverseOrder()); 
嘗試

我的IntelliJ沒有說什麼,而我的編譯器說:

DateUtils.java:[302,48]不兼容的類型;沒有類型的實例 變量K,V存在以便java.util.TreeMap符合 java.util.Map [錯誤] 找到:java.util.TreeMap [錯誤]必需: java。 util.Map

它工作正常,沒有比較:

Map<TimeUnit,Long> map = Maps.newTreeMap(); 

但是我試着用:

Map<TimeUnit,Long> map = Maps.newTreeMap(Collections.<TimeUnit>reverseOrder()); 

而且具有:

Map<TimeUnit,Long> map = Maps.newTreeMap(new Comparator<TimeUnit>() { 
    @Override 
    public int compare(TimeUnit timeUnit, TimeUnit timeUnit1) { 
     return 0; 
    } 
}); 

而且我得到了同樣的錯誤。 因此,似乎每次我在TreeMap中使用比較器時,類型推斷不再有效。 爲什麼?


的番石榴方法的簽名是:

public static <C, K extends C, V> TreeMap<K, V> newTreeMap(Comparator<C> comparator) 

的預期收益類型爲類型的,沒有比較,Java是能夠推斷K = TIMEUNIT和V =長。

對於類型爲TimeUnit的比較器,Java知道C是TimeUnit。它也知道期望的返回類型是K = TimeUnit和V = Long的類型。 由於TimeUnit擴展了TimeUnit,因此K擴展C是受到尊重的(無論如何,如果您認爲它是錯誤的,我也嘗試使用Object比較...)

所以我只是想知道爲什麼類型推斷在這種情況下不起作用?

+0

願你的問題涉及到這個問題? http://code.google.com/p/guava-libraries/issues/detail?id=635 –

+0

是很可能的,因爲我使用的OpenJDK。 –

+0

基本相同,你的問題[這裏](http://stackoverflow.com/questions/10945616/whats-this-generics-usage-in-java),使用的特定形式的地圖。 newTreeMap (......)。 – kutschkem

回答

7

像邁克爾Laffargue建議,這是一個OpenJDK6類型推斷的錯誤:

https://bugs.openjdk.java.net/show_bug.cgi?id=100167

http://code.google.com/p/guava-libraries/issues/detail?id=635

它工作正常,在我的IntelliJ,並與OpenJDK的版本7中,並與他人JDK在版本6中。


kutschkem的以下建議工作:

Map<TimeUnit,Long> map = Maps.<TimeUnit,TimeUnit,Long>newTreeMap(Collections.<TimeUnit>reverseOrder()); 

通知的<TimeUnit,TimeUnit,Long>允許迫使類型參數明確。 選中此相關的主題:What's this generics usage in Java? X.<Y>method()

感謝所有

+0

以上不再適用於OpenJDK的鏈接只有2類型的參數,但我相信HTTPS: //bugs.openjdk.java.net/browse/JDK-6569074是相同或相似的。 – andrewdotn