2012-06-08 4 views
6

ho scritto un metodo di utilità in Java:java6, Guava, farmaci generici, inferenza di tipo

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; 
} 

Funziona con:

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

Ma prima ho provato con

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

My IntelliJ non dice nulla, mentre il mio compilatore dice:

DateUtils.java:[302,48] tipi incompatibili; nessuna istanza (s) di tipo variabile (s) K, V esiste in modo che java.util.TreeMap è conforme a java.util.Map [ERRORE] trovato: java.util.TreeMap [ERROR] richiesto: java. util.Map

funziona bene anche senza il comparatore:

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

ma ho provato con:

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

E con:

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

E ho ottenuto lo stesso errore. Quindi sembra che ogni volta che sto usando un comparatore nella TreeMap, l'inferenza di tipo non funzioni più. Perché?


La firma del metodo Guava è:

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

Il tipo rendimento atteso è di tipo quindi senza un comparatore, Java è in grado di dedurre che K = TIMEUNIT e V = lunga.

Con un comparatore di tipo TimeUnit, Java sa che C è TimeUnit. Sa anche che il tipo di reso previsto è di tipo quindi K = TimeUnit e V = Long. K ext è rispettato poiché TimeUnit estende TimeUnit (comunque ho provato anche con un comparatore di oggetti se si pensa che sia sbagliato ...)

Quindi mi chiedo perché il tipo di inferenza non funziona in questo caso?

+0

Possa il vostro problema essere correlato a questo problema? http://code.google.com/p/guava-libraries/issues/detail?id=635 –

+0

Sì, potrebbe essere, dal momento che sto usando OpenJDK. –

+0

fondamentalmente uguale alla tua domanda [qui] (http://stackoverflow.com/questions/10945616/whats-this-generics-usage-in-java), usa il modulo specifico Maps. newTreeMap (...). – kutschkem

risposta

7

Come Michael Laffargue suggerito, si tratta di un bug di tipo openjdk6 inferenza:

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

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

Funziona bene nel mio IntelliJ, e con un OpenJDK nella versione 7, e con gli altri JDK nella versione 6.


Il seguente suggerimento del kutschkem funziona:

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

Avviso del <TimeUnit,TimeUnit,Long> che permette di forzare i parametri digitati in modo esplicito. Controllare questo argomento correlato: What's this generics usage in Java? X.<Y>method()

Grazie a tutti

+0

Il link openjdk sopra non funziona più, ma credo che https: //bugs.openjdk.java.net/browse/JDK-6569074 è uguale o simile. – andrewdotn