使用java泛型时如何解决此通配符捕获问题?

Sim*_*ins 5 java generics bounded-wildcard

我在使用java泛型时遇到问题 - 特别是使用通配符捕获.这是我所拥有的代码的简化版本,它展示了我所看到的问题.这让我抓狂:

public class Task {

    private Action<ActionResult, ? extends ActionSubject> action;
    private ActionSubject subject = new ActionSubjectImpl();

    private List<ActionResult> list = new ArrayList<>();

    public static void main(String[] args) {
        Task task = new Task();
        task.setAction(new ActionImpl());
        task.doAction();
    }

    public void setAction(Action<ActionResult, ? extends ActionSubject> action) {
    this.action = action;
    }

    public void doAction() {
        list.add(action.act(subject));
    }      

    public static class ActionResult { }

    public interface Action<T, U> {
        public T act(U argument);
    }    

    public interface ActionSubject {
        public String getName();
    }

    public static class ActionImpl implements Action<ActionResult, ActionSubjectImpl>{
        @Override
        public ActionResult act(ActionSubjectImpl argument) {
            // Code that requires ActionSubjectImpl specifically instead of the interface.
            // This classes implmentation of action should only support ActionSubjectImpl as an
            // argument.
            return new ActionResult();
        }
    }

    public class ActionSubjectImpl implements ActionSubject {
        @Override
        public String getName() {
            return "I am a subject";
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

包含声明和导入不包括在内 - 否则这是完整的.这不编译.问题是list.add(action.act(subject));我看到错误消息的片段:

incompatible types: ActionSubject cannot be converted to CAP#1
 where CAP#1 is a fresh type-variable:
  CAP#1 extends ActionSubject from ? extends ActionSubject
Run Code Online (Sandbox Code Playgroud)

我可以从其他帖子中看到辅助方法被建议作为一种方式使这样的事情起作用,但我无法想出一个有效的方法.

Action action有类型参数,像这样:Action<ActionResult, ? extends ActionSubject>ActionSubject,我传递的act方法是接口类型"ActionSubject"和具体类型的"ActionSubjectImpl"的,虽然有问题的代码片段将不会看到具体的类型的课程.第二个类型参数Action应该支持任何扩展的类型ActionSubject- 当我设置actionnew ActionImpl()第二种类型时,它是正常的ActionSubjectImpl.

在我的定义和泛型的使用中,我将不胜感激任何关于我在做错的评论.我可能会遗漏一些基本的东西.我可以用不同的方式对此进行编码,但在我明白出现问题之前,我将无法继续前进.

谢谢.

MFo*_*ter 10

这是你的误解:你说:

第二个类型参数Action应该支持任何扩展的类型ActionSubject

这是不正确的.第二类型参数Action被约束为ActionSubject例如的特定子类MyActionSubject.因此,您无法传递任意ActionSubject实例,因为这是一种更通用的类型.

如果你想拥有任意子类型ActionSubject,只需使用ActionSubject第二个类型参数而不是? extends ActionSubject.