适合此特定使用场景的Java Generics

时间:2013-10-16 11:35:10

标签: java generics

首先抱歉不是非常具体的标题,但我找不到更好的简短描述性标题!

我有一个这样的界面:

public interface ModelInterface {        
    public List<? extends Umbrella> getBRs();
}

以及这种模式的几个实现类:

public class Model implements ModelInterface {
    // need to use the concrete impl here because of JPA
    List<StoneUmbrella> _list = new ArrayList<>(); 

    @Override
    public List<? extends Umbrella> getBRs() {
        return _list;
    }
}

到目前为止一切顺利。但我也有以下Util类:

import java.util.Collection;

public abstract class Util<E, R> {

    public R reduce(Collection<E> collection, R initialElement) {
        R result = initialElement;
        for (E currElement : collection) {
            result = reduce(result, currElement);
        }
        return result;
    }

    abstract R reduce(R initialElement, E element);
}

现在当我尝试在我的主代码中调用该Utility类时出现问题:

import java.util.List;

public class Main {
    public static void main(String[] args) {
        ModelInterface model = new Model();

        List<? extends Umbrella> list = model.getBRs();

        Util<Umbrella, Boolean> util = new Util<Umbrella, Boolean>() {
            @Override
            Boolean reduce(Boolean initialElement, Umbrella element) {
                return Boolean.TRUE;
            }
        };

        util.reduce(list, Boolean.FALSE);
    }
}

util.reduce 行无法使用此消息进行编译: Util类型中的reduce(Collection,Boolean)方法不适用于参数(List&lt; capture#2-of?extends Umbrella&gt;,Boolean)

当我使用List&lt; Umbrella&gt;时,它可以正常工作而不是列表&lt;?扩展Umbrella&gt;但我不能在模型接口中更改它,否则我将无法在getter中返回其内部列表。我认为不可能以满足两个方面的方式实现它。

有人可以帮忙吗? 在此先感谢!!

3 个答案:

答案 0 :(得分:1)

此变体编译:

public class ListUmbrella {
    public static void main(String[] args) {
        ModelInterface<StoneUmbrella> model = new Model();
        List<StoneUmbrella> list = model.getBRs();
        Util<StoneUmbrella, Boolean> util = new Util<StoneUmbrella, Boolean>() {
            @Override
            Boolean reduce(Boolean initialElement, StoneUmbrella element) {
                return Boolean.TRUE;
            }
        };

        util.reduce(list, Boolean.FALSE);
    }
}

interface ModelInterface<T extends Umbrella> {
    public List<T> getBRs();
}

class Model implements ModelInterface<StoneUmbrella> {
    List<StoneUmbrella> _list = new ArrayList<StoneUmbrella>();

    @Override
    public List<StoneUmbrella> getBRs() {
        return _list;
    }
}

答案 1 :(得分:1)

泛型中的参数必须完全相同。您不能在此处遵循继承层次结构。 你要做的是有效

Collection<Umbrella> test = new ArrayList<StoneUmbrella>();

但你应该做

Collection<StoneUmbrella> test = new ArrayList<StoneUmbrella>();

不确定您可以使用Model类做什么。但我会尝试将其更改为以下内容并相应地解决。

public interface ModelInterface<T extends Umbrella> {        
    public List<T> getBRs();
}

如果您需要上述解决方案的完整代码,请告诉我。如果你不能对ModelInterface做任何事情,我不想重载,我没有任何其他好的答案。

答案 2 :(得分:-1)

util.reduce方法的语法有误。请更正为:

 public R reduce(Collection<? extends E> collection, R initialElement)