Seb*_*ber 6 java generics scjp type-inference 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;
}
Run Code Online (Sandbox Code Playgroud)
它适用于:
Map<TimeUnit,Long> map = new TreeMap<TimeUnit,Long>(Collections.reverseOrder());
Run Code Online (Sandbox Code Playgroud)
但我第一次尝试
Map<TimeUnit,Long> map = Maps.newTreeMap(Collections.reverseOrder());
Run Code Online (Sandbox Code Playgroud)
我的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();
Run Code Online (Sandbox Code Playgroud)
但我尝试过:
Map<TimeUnit,Long> map = Maps.newTreeMap(Collections.<TimeUnit>reverseOrder());
Run Code Online (Sandbox Code Playgroud)
与:
Map<TimeUnit,Long> map = Maps.newTreeMap(new Comparator<TimeUnit>() {
@Override
public int compare(TimeUnit timeUnit, TimeUnit timeUnit1) {
return 0;
}
});
Run Code Online (Sandbox Code Playgroud)
我得到了同样的错误.所以每当我在TreeMap中使用比较器时,类型推断似乎不再起作用.为什么?
番石榴方法的签名是:
public static <C, K extends C, V> TreeMap<K, V> newTreeMap(Comparator<C> comparator)
Run Code Online (Sandbox Code Playgroud)
预期的返回类型是类型,因此没有比较器,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());
Run Code Online (Sandbox Code Playgroud)
注意<TimeUnit,TimeUnit,Long>哪个允许显式强制输入类型的参数.查看相关主题:Java中的这种泛型用法是什么?X. <Y>()的方法
谢谢大家
| 归档时间: |
|
| 查看次数: |
1938 次 |
| 最近记录: |