2013-07-08 27 views
17

Dlaczego kompilator jest w stanie określić ogólny typ parametru dla przypisania , ale nie dla operatora trójskładnikowego (?)?Czy w Javie nie można wywnioskować ogólnego typu parametru podczas korzystania z operatora trójskładnikowego (`?`)?

I pytanie odnośnie kompilator jest w stanie wywnioskować, ogólny typ parametru w przypadku „bezpośrednie” przydział, ale uszkodzonej w przypadku trójskładnikowych operatora (?). Moje przykłady używają klasy Guava Optional, aby przedstawić mój punkt, ale Myślę, że podstawowy problem jest ogólny i nie ogranicza się do Optional.

Optional ma ogólną funkcję absent():

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

i mogę przypisać Optional<T> do Optional<Double>:

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

W jaki sposób uświadomić sobie kompilatora, że ​​T powinny być Double w tym przypadku. Ponieważ przy użyciu operatora potrójny (?), muszę powiedzieć, że kompilator specjalnie nam Integer jak generycznego parametru

// 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(); 

inaczej pojawia się następujący błąd

Niezgodność typów: nie można przekonwertować od Optional<capture#1-of ? extends Object> do Optional<Integer>

Dlaczego istnieje różnica między "bezpośrednim" przypisaniem i używaniem operator trójskładnikowy ? Czy jest jeszcze coś, czego mi brakuje?

+0

jaki jest typ zwrotu metody 'of'? – sanbhat

+0

Taki sam jak 'nieobecny()': 'public static Opcjonalnie (T reference);' –

+0

Z którą wersją javac kompilujesz to? – Vincent

Odpowiedz

9

Z powodu reguł wnioskowania typu, wydaje się, że wyrażenie potrójne nie wywnioskuje parametru type z typu zwracanego. Typ wyrażenia trójskładnikowego zależy od typów jego operandów. Ale jeden z argumentów ma nieokreślony parametr typu (Optional.absent()). W tym momencie wyrażenie potrójne nadal nie ma typu, więc nie może wpływać na parametr typu.

Możesz również zajrzeć do tego bug report, aby uzyskać więcej informacji. Możesz zajrzeć do JLS.

typu wyrażenia warunkowego jest wynikiem stosowania konwersji przechwytywania (?? 5.1.10) na interfejsie lub (T1, T2)

Oto co JLS mówi:

Jeśli wynik metody występuje w kontekście, w którym będzie podlegał konwersji przypisania do typu S, niech R będzie deklarowanym wynikiem metody i niech R '= R [T1 = B (T1) ... Tn = B (Tn)] gdzie B (Ti) jest typem wywnioskowanym dla Ti w poprzedniej sekcji, lub Ti, jeśli nie wywnioskowano żadnego typu.

5

Problem polega na tym, że wynik potrójnego Operatora jest przypisany do o2. Kompilator nie może wywnioskować typu dla wielu operacji.

Zasadniczo myślę, piszesz krótkie formy:

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

Konwersję drugiej linii jest problem.

Powiązane problemy