我无法通过通配符理解Java泛型的细节。具体来说,为什么不编译。
public class Test {
abstract class Function<A, B> {
abstract B call(A a);
}
interface PropertyType {
String bubbles();
}
class Apartment implements PropertyType {
@Override
public String bubbles() {
return "bubbles";
}
}
public void invokeFunctionOnAList() {
List<Apartment> apts = new ArrayList<Apartment>();
functionLoop(apts, new Function<Apartment, String>() {
@Override
String call(Apartment a) {
return a.bubbles();
}
});
}
public void functionLoop(List<? extends PropertyType> list, Function<? extends PropertyType, String> t) {
for (PropertyType p : list) {
t.call(p);
}
}
}
答案 0 :(得分:3)
实际放置该代码的最正式的正确方法是
public <C extends PropertyType> void functionLoop(
List<C> list, Function<? super C, String> t) {
for (C p : list) {
t.call(p);
}
}
我发现的仿制药的最佳解释是Joshua Bloch撰写的“Effective Java”。您可以在此presentation中找到与您的示例相关的小摘录。
答案 1 :(得分:1)
您的编译器不知道您是否在List和Function中使用相同的类型。所以你必须告诉他。
试试这个:
public <C extends PropertyType>void functionLoop(
List<C> list, Function<C, String> t) {
for (C p : list) {
t.call(p);
}
}
答案 2 :(得分:0)
因为call(Apartment a)
应该将Apartment
个对象作为参数,然后传递PropertyType
个对象。 Apartment
是PropertyType
,但PropertyType
是非Appartment
。