【问题标题】:Java6, Guava, generics, type inferenceJava 6、Java、泛型、类型推断
【发布时间】:2012-06-08 08:33:07
【问题描述】:

我用 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 [错误] 发现:需要 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(无论如何,如果您认为它是错误的,我也尝试使用 Object 比较器......)

所以我只是想知道为什么类型推断在这种情况下不起作用?

【问题讨论】:

  • 您的问题可能与此问题有关吗? code.google.com/p/guava-libraries/issues/detail?id=635
  • 是的,因为我使用的是 OpenJDK。
  • 和你的问题here基本一样,使用具体形式Maps。newTreeMap(...)。
  • @kutschkem 与我的 OpenJDK 它在 javac/maven 或 intellij 中都不起作用
  • 对不起@kutschkem 它工作正常我只放了 2 个类型参数而不是 3 个

标签: java generics guava type-inference scjp


【解决方案1】:

就像 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());

注意&lt;TimeUnit,TimeUnit,Long&gt;,它允许显式地强制输入类型参数。 检查此相关主题:What's this generics usage in Java? X.<Y>method()

谢谢大家

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-04-01
  • 2015-07-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-28
相关资源
最近更新 更多