Java6, Guava, generics, type inference

I wrote a utility in 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; } 

It works with:

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

But I tried it first

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

My IntelliJ says nothing, and my compiler says:

DateUtils.java: [302,48] incompatible types; no instance (s) of type variable K, V exists so that java.util.TreeMap matches java.util.Map [ERROR] found: java.util.TreeMap [ERROR] required: java.util.Map

It works fine without a comparator:

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

But I tried:

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

And with the help of:

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

And I have the same error. So it seems that every time I use a comparator in TreeMap, type inference no longer works. Why?


Guava Method Signature:

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

The expected type of the return type is of type, so without a comparator, Java can conclude that K = TimeUnit and V = Long.

Using a comparator like TimeUnit, Java knows that C is TimeUnit. He also knows that the expected return type is of type therefore K = TimeUnit and V = Long. K extends C is respected since TimeUnit extends TimeUnit (anyway, I also tried to use Object Comparator if you think this is wrong ...)

So just wondering why type inference doesn't work in this case?

+6
source share
1 answer

As Michael Laffarg suggested, this is an OpenJDK6 type output error:

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

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

It works great in my IntelliJ and with OpenJDK in version 7, and with other JDKs in version 6.


The following kutschkem works offer:

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

Pay attention to <TimeUnit,TimeUnit,Long> , which allows you to force typed parameters. Check this topic: What is the use of generics in Java? X. <Y> () method

Thank you all

+7
source

Source: https://habr.com/ru/post/917598/


All Articles