Mam następujący pozornie podobnych metod, do1
i do2
:dlaczego java wnioskowanie nie
class Demo<A>{
public <C> Iterable<C> do1(List<? super C> _a) {
return null;
}
public <C extends D, D> Iterable<C> do2(List<D> _a) {
return null;
}
{
List<? extends A> leA = null;
do2(leA);
do1(leA);
}
}
Kiedy skompilować powyższy kod (javac 1.8.0_92), nazywając do2(leA)
prace podczas do1(leA)
zawiedzie.
required: List<? super C>
found: List<CAP#1>
reason: cannot infer type-variable(s) C
(argument mismatch; List<CAP#1> cannot be converted to List<? super C>)
where C,A are type-variables:
C extends Object declared in method <C>do1(List<? super C>)
A extends Object declared in class Cache
where CAP#1 is a fresh type-variable:
CAP#1 extends A from capture of ? extends A
Teraz zastanawiam się: czy to ze względu na niepełną realizację typu wnioskowania w javac, albo ja tworzenia nieprawidłowy typu drzewo z wezwaniem do1(leA)
?
Bo według mojej wiedzy:
- w
do1(leA)
:Capture(? extends A)
staje się supertypem od C - w
do2(leA)
:Capture(? extends A)
staje się supertypem C (pośrednio przez:Capture(? extends A) == D
iD :> C
znaczenia w obu sytuacjach C
powinien (bez błędów) rozwiązać na "? extends A"
Mogę odtworzyć to z JDK 1.8.0_51. FYI, Eclipse Mars.2 kompiluje to dobrze ... – Tunaki
Kompiluje OK dla mnie też używając '1.8.0_91-b14'. IIRC, aktualizacja 40 była błędna - mógł to być jeden z błędów. Może po prostu zaktualizuj swoją wersję Java. – Bohemian
dzięki za aktualizację do wersji 1.8.0_92 nadal otrzymuję ten sam błąd kompilacji: http://pastebin.com/tEUfX2JC –