使用通配符编译的Java泛型

时间:2010-11-16 11:43:19

标签: java generics wildcard

我无法通过通配符理解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);
        }
    }
}

3 个答案:

答案 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个对象。 ApartmentPropertyType,但PropertyType是非Appartment