简体   繁体   English

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

[英]How do I resolve this wildcard capture issue when using java generics?

I am having issues using java generics - specifically, using wildcard capture. 我在使用java泛型时遇到问题 - 特别是使用通配符捕获。 Here is a simplified version of the code I have that exhibits the problem I am seeing. 这是我所拥有的代码的简化版本,它展示了我所看到的问题。 It is driving me crazy: 这让我抓狂:

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";
        }
    }
}

Package declaration and imports are not included - otherwise this is complete. 包含声明和导入不包括在内 - 否则这是完整的。 This does not compile. 这不编译。 The problem is with the fragment list.add(action.act(subject)); 问题在于片段list.add(action.act(subject)); where I am seeing the error message : 我在哪里看到错误消息:

incompatible types: ActionSubject cannot be converted to CAP#1
 where CAP#1 is a fresh type-variable:
  CAP#1 extends ActionSubject from ? extends ActionSubject

I can see from other posts that helper methods are suggested as a way get things like this to work, but I have not been able to come up with one that works. 我可以从其他帖子中看到辅助方法被建议作为一种方式使这样的事情起作用,但我无法想出一个有效的方法。

The Action action has the type parameters like so: Action<ActionResult, ? extends ActionSubject> Action action的类型参数如下: Action<ActionResult, ? extends ActionSubject> Action<ActionResult, ? extends ActionSubject> and the ActionSubject that I am passing in to the act method is of interface type 'ActionSubject' and of concrete type 'ActionSubjectImpl' although the code fragment in question will not see the concrete type of course. Action<ActionResult, ? extends ActionSubject>ActionSubject ,我传递到act方法是接口类型“ActionSubject”的和具体类型的“ActionSubjectImpl”虽然有问题的代码片段将不会看到具体类型的课程。 The second type parameter of Action should support any type that extends ActionSubject - and it is fine when I set action to new ActionImpl() , where the second type is ActionSubjectImpl . Action的第二个类型参数应该支持任何扩展ActionSubject类型 - 当我将action设置为new ActionImpl()时,它是正常的,其中第二个类型是ActionSubjectImpl

I would appreciate any comment on what I am doing wrong here in my definitions and use of generics. 在我的定义和泛型的使用中,我将不胜感激任何关于我在做错的评论。 I may be missing something basic here. 我可能会遗漏一些基本的东西。 I could code this a different way, but until I understand what is going wrong I won't be able to move on. 我可以用不同的方式对此进行编码,但在我明白出现问题之前,我将无法继续前进。

Thanks. 谢谢。

Here is your misunderstanding: You said: 这是你的误解:你说:

The second type parameter of Action should support any type that extends ActionSubject Action的第二个类型参数应该支持任何扩展ActionSubject类型

This is not correct. 这是不正确的。 The second type parameter of Action is constrained to be a specific subclass of ActionSubject , eg, MyActionSubject . Action的第二个类型参数被约束为ActionSubject的特定子类,例如MyActionSubject So you can't pass in an arbitrary ActionSubject instance, because that's a more generic type. 所以你不能传入一个任意的ActionSubject实例,因为那是一个更通用的类型。

If you want to have arbitrary subtypes of ActionSubject , just use ActionSubject as the second type parameter instead of ? extends ActionSubject 如果你想拥有ActionSubject任意子类型,只需使用ActionSubject作为第二个类型参数而不是? extends ActionSubject ? extends ActionSubject . ? extends ActionSubject

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM