Java può spesso dedurre generici basati sugli argomenti (e anche sul tipo restituito, al contrario di ad esempio C#).Generics con caratteri jolly dedotti nel tipo di ritorno
Caso in questione: io ho una classe generica Pair<T1, T2>
che ha appena memorizza una coppia di valori e può essere utilizzato nel modo seguente:
Pair<String, String> pair = Pair.of("Hello", "World");
Il metodo of
sembra proprio come questo:
public static <T1, T2> Pair<T1, T2> of(T1 first, T2 second) {
return new Pair<T1, T2>(first, second);
}
Molto bello. Tuttavia, questo non lavora più per il seguente caso d'uso, che richiede i caratteri jolly: (. Si noti il cast esplicito di rendere List.class
il tipo corretto)
Pair<Class<?>, String> pair = Pair.of((Class<?>) List.class, "hello");
Il codice non riesce con il seguente errore (a condizione da Eclipse):
Tipo non corrispondente: non può convertire da
TestClass.Pair<Class<capture#1-of ?>,String>
aTestClass.Pair<Class<?>,String>
Tuttavia, in modo esplicito chiamando il costruttore funziona ancora come previsto:
Pair<Class<?>, String> pair =
new Pair<Class<?>, String>((Class<?>) List.class, "hello");
qualcuno può spiegare questo comportamento? È di progettazione? È desiderato? Sto facendo qualcosa di sbagliato o mi sono imbattuto in un difetto nella progettazione/bug nel compilatore?
indovinare: la “cattura # 1-di?” Sembra in qualche modo implicare che il carattere jolly viene compilato dal compilatore al volo, rendendo il tipo di un Class<List>
, e non riuscendo in tal modo la conversione (Pair<Class<?>, String>
-Pair<Class<List>, String>
) . È giusto? C'è un modo per aggirare questo?
Per completezza, qui è una versione semplificata della classe Pair
:
public final class Pair<T1, T2> {
public final T1 first;
public final T2 second;
public Pair(T1 first, T2 second) {
this.first = first;
this.second = second;
}
public static <T1, T2> Pair<T1, T2> of(T1 first, T2 second) {
return new Pair<T1, T2>(first, second);
}
}
Sembra che il convertitore veda la firma di "of" mentre restituisce una coppia ,? estende Classe> tipo. Per le classi finali sembra abbastanza intelligente da ridurre la parte estesa, ecco perché non si lamenta della stringa. –
Zed
Hmmm, interessante. Grazie per avermi collegato qui. – jjnguy
Ora funziona con java8. Anche il tipo di bersaglio viene consultato per inferene. – ZhongYu