Java6, Guava, обобщения, вывод типов

Я написал служебный метод на 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.Карта [ОШИБКА] найдено: требуется 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, вывод типа больше не работает. Почему?


Сигнатура метода Guava:

  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 (во всяком случае, я пробовал также с компаратором объектов, если вы думаете, что это неправильно...)

Так что мне просто интересно, почему вывод типа не работает в этом случае?

6
задан Sebastien Lorber 8 June 2012 в 08:33
поделиться