簡體   English   中英

Java6,番石榴,泛型,類型推斷

[英]Java6, Guava, generics, type inference

我在Java中編寫了一個實用工具方法:

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 [ERROR] found:java.util.TreeMap [ERROR] required: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 = Long。

使用TimeUnit類型的比較器,Java知道C是TimeUnit。 它還知道預期的返回類型是類型,因此K = TimeUnit,V = Long。 K擴展C受到尊重,因為TimeUnit擴展了TimeUnit(無論如何,如果你認為它是錯誤的話,我還嘗試使用對象比較器......)

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

像Michael Laffargue建議的那樣,它是一個OpenJDK6類型的推理錯誤:

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

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

它在我的IntelliJ中運行良好,在版本7中使用OpenJDK,在版本6中使用其他JDK。


以下關於kutschkem的建議:

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

注意<TimeUnit,TimeUnit,Long>允許顯式強制輸入類型的參數。 查看相關主題: Java中的這種泛型用法是什么? X. <Y>()的方法

謝謝大家

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM