I don't understand the compiler error resulting from the following code. I define a generic interface, see Task, with two methods: U doSomething(String value)
and List<Integer> getIDs()
. The doSomething() method actually uses the generic type as the type of its return value, but doesn't seem to be causing problems. The getIDs()
method returns a List, which is unrelated to the type of Task, but it is causing problems when using for..each statement to iterate over the return value. The following compiler error occurs.
error: incompatible types for (Integer value : task.getIDs()){ required: Integer found: Object
It seems that the type erasure on the interface is causing the compiler to forget the declared type on the second method, which is unrelated to the generic type. Or in other words why is the generic type on the interface affecting how the compiler understands the return value on the getIDs()
method and specifically in the context of a for..each statement?
Apparently if I get reference to the list outside of the for..each there is no problem, but not directly.
public class InterfaceTest {
public static void main(String[] args) {
Task task = new MyTask();
// no complaints about the type here
List<Integer> values = task.getIDs();
// getting a compiler error for this line
for (Integer value : task.getIDs()){
}
}
}
interface Task<U>{
U doSomething(String value);
List<Integer> getIDs();
}
The implementation of the interface isn't necessary to demonstrate the point, but I didn't want to leave the reference Task task = null;
and have answer's telling me that's the problem.
class MyTask implements Task<Boolean>{
@Override
public Boolean doSomething(String value) {
System.out.println(value);
return false;
}
@Override
public List<Integer> getIDs() {
return Arrays.asList( 1, 2, 3, 4 );
}
}