1

父类:

public class Action
    {
        private String eventId;
        private List<ActionArgument> arguments;
        //action to perform when this action is done
        private List<? extends Action> onCompleteActions;

        public Action(){}

        public Action(String eventId, List<ActionArgument> arguments, List<? extends Action> onCompleteActions)
        {
            this.eventId = eventId;
            this.arguments = arguments;
            this.onCompleteActions = onCompleteActions;
        }

        public String getEventId()
        {
            return eventId;
        }
        public void setEventId(String eventId)
        {
            this.eventId = eventId;
        }
        public List<ActionArgument> getArguments()
        {
            return arguments;
        }
        public void setArguments(List<ActionArgument> arguments)
        {
            this.arguments = arguments;
        }
        public List<? extends Action> getOnCompleteActions()
        {
            return onCompleteActions;
        }
        public void setOnCompleteActions(List<? extends Action> onCompleteActions)
        {
            this.onCompleteActions = onCompleteActions;
        }
    }

扩展类:

public class UserDefinedAction extends Action
{
    // body not important
}

一些服务:

private boolean arrangeBefore(List<? extends Action> defaultActions, UserDefinedAction action)
    {
        String actionToFind = action.getDoBefore();
        boolean actionFound = false;
        for(int i = 0; i < defaultActions.size(); i++)
        {
            if(defaultActions.get(i).getEventId().toUpperCase().equals(actionToFind.toUpperCase()))
            {
                defaultActions.add(i, action);
                return true;
            }
...

所以我在这里有一个错误:defaultActions.add(i, action);上面写着“

add
(int,
capture<? extends com.myPackage.Action>)
in List cannot be applied
to
(int,
com.myPackage.UserDefinedAction)

"

有人可以向我解释为什么这不起作用吗?

4

3 回答 3

1

A simple possibility to consider is:

  • Make a defensive copy of the input list in the constructor.
  • Store it simply as a List<Action>.

In general, it's useful to remember the PECS acronym - Producer Extends, Consumer Super. If you want to add elements to a List with a bounded type variable or wildcard, you'd want to express it with super rather than extends. For example, List<? super A> means that the list member type is some superclass of an A.

于 2013-08-08T23:12:39.497 回答
0

您不能将任何类型的参数传递给其中带有通配符的方法。在这里,您有一个List<? extends Action>,并且您正在尝试添加一个UserDefinedAction.

但是Java不知道你的确切泛型类型List;它假设它可以是任何东西,甚至像List<SomeOtherAction>. UserDefinedAction出于这个原因,它不允许您将 a 添加到您的列表中。出于这个原因,Java 不允许您调用这样的方法。

为了解决这个问题,你需要在你的Action类上定义一个泛型类型参数:

public class Action<A extends Action>

然后,您可以<? extends Action>将该类中的所有内容替换为<E>. 这样, anAction<Action>将能够处理 a List<Action>

接下来,将Ain定义UserDefinedActionUserDefinedAction。这样, aUserDefinedAction可以处理 a List<UserDefinedAction>,这将允许您adda UserDefinedAction

public class UserDefinedAction extends Action<UserDefinedAction>

或者,为了获得更大的灵活性,您可以UserDefinedAction这样定义:

public class UserDefinedAction<A extends UserDefinedAction> extends Action<A>

...并使用一个UserDefinedAction<UserDefinedAction>实例。这将允许进一​​步的子类以他们想要的方式UserDefinedAction定义泛型类型参数。A

于 2013-08-08T23:00:53.747 回答
0

您可以更改方法的签名并在其中使用泛型:

public <A extends Action> void arrangeBefore(List<A> actionList, A action) {
    actionList.add(action);
}

请注意,此更改假定 in 中使用的方法A actionarrangeBefore属于Action类。

于 2013-08-08T23:12:22.230 回答