2013-07-08 10 views
17

Perché il compilatore è in grado di determinare il parametro di tipo generico per un incarico , ma non per l'operatore ternario (?)?Java non riesce a dedurre il parametro di tipo generico quando usa l'operatore ternario (`?`)?

Ho una domanda per quanto riguarda il compilatore in grado di dedurre il parametro generico tipo in caso di assegnazione "diretta", ma non riuscendo nel caso del operatore ternario (?). I miei esempi utilizzano la classe Optional di Guava, per rendere il mio punto, ma Penso che il problema di fondo sia generico e non limitato a Optional.

Optional ha una funzione generica absent():

public static <T> Optional<T> absent(); 

e posso assegnare un Optional<T> a un Optional<Double>:

// no compiler error 
final Optional<Double> o1 = Optional.absent(); 

Come funziona il rendersi conto del compilatore, che T dovrebbe essere Double in questo caso. Perché quando si utilizza l'operatore ternario (?), ho bisogno di dire al compilatore specificamente a noi Integer come parametro generico

// Type mismatch: cannot convert from Optional<capture#1-of ? extends Object> to Optional<Integer> 
final Optional<Integer> o2 = true 
    ? Optional.of(42) 
    : Optional.<Integer>absent(); 

altrimenti il ​​seguente errore

Tipo non corrispondente: non può convertire da Optional<capture#1-of ? extends Object> a Optional<Integer>

Perché c'è una differenza tra un "diretto" e l'utilizzo di l'operatore ternario ? O c'è qualcos'altro che mi manca?

+0

qual è il tipo di ritorno del metodo 'of'? – sanbhat

+0

Uguale a 'absent()': 'statico pubblico facoltativo di (riferimento T);' –

+0

Quale versione di javac stai compilando? – Vincent

risposta

9

A causa delle regole di inferenza del tipo, sembra che l'espressione ternaria non inferisca il parametro type dal tipo restituito. Il tipo di espressione ternaria dipende dai tipi dei suoi operandi. Ma uno degli operandi ha un parametro di tipo indeterminato (Optional.absent()). A quel punto l'espressione ternaria non ha ancora un tipo, quindi non può influenzare il parametro type.

È inoltre possibile esaminare questo bug report per ulteriori informazioni. Puoi guardare nello JLS.

Il tipo dell'espressione condizionale è il risultato dell'applicazione di conversione di cattura (?? 5.1.10) per LUB (T1, T2)

Ecco ciò che il JLS dice:

Se il risultato del metodo si verifica in un contesto in cui sarà soggetto alla conversione dell'assegnazione a un tipo S, allora sia R il tipo di risultato dichiarato del metodo e sia R '= R [T1 = B (T1) ... Tn = B (Tn)] dove B (Ti) è il tipo inferito per Ti nella sezione precedente, o Ti se nessun tipo è stato inferito.

5

Il problema è che il risultato dell'operatore ternery è assegnato a o2. Il compilatore non può dedurre il tipo attraverso più operazioni.

Fondamentalmente credo si scriva la forma abbreviata di:

Optional<?> tmp = true ? Optional.of(42): Optional.absent(); 
final Optional<Integer> o2 = tmp; 

La conversione della seconda linea è il problema.

Problemi correlati