家长班:
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)
“
有人可以向我解释为什么这不起作用吗?
答案 0 :(得分:1)
一个简单的考虑因素是:
一般来说,记住 PECS 首字母缩写 - Producer Extends,Consumer Super 是很有用的。如果要使用有界类型变量或通配符向List添加元素,则需要使用super
而不是extends
来表达它。例如,List&lt;?超级A&gt;表示列表成员类型是A的一些超类。
答案 1 :(得分:0)
您不能将任何类型的参数传递给其中带有通配符的方法。在这里,您有一个List<? extends Action>
,并且您尝试添加UserDefinedAction
。
但是Java并不知道List
的确切泛型类型;它假设它可以是任何东西,甚至像List<SomeOtherAction>
之类的东西。由于这个原因,您无法在列表中添加UserDefinedAction
。出于这个原因,Java不允许你调用这样的方法。
要解决此问题,您需要在Action
类上定义泛型类型参数:
public class Action<A extends Action>
然后,您可以使用<? extends Action>
替换该班级中的所有<E>
。这样,Action<Action>
就可以处理List<Action>
。
接下来,将A
中的UserDefinedAction
定义为UserDefinedAction
。这样,UserDefinedAction
可以处理List<UserDefinedAction>
,这样您就可以add
UserDefinedAction
。
public class UserDefinedAction extends Action<UserDefinedAction>
或者,您可以更灵活地以这种方式定义UserDefinedAction
:
public class UserDefinedAction<A extends UserDefinedAction> extends Action<A>
...并使用UserDefinedAction<UserDefinedAction>
实例。这将允许UserDefinedAction
的更多子类以他们想要的方式定义泛型类型参数A
。
答案 2 :(得分:0)
您可以更改方法的签名并在其中使用泛型:
public <A extends Action> void arrangeBefore(List<A> actionList, A action) {
actionList.add(action);
}
请注意,此更改假定A action
中arrangeBefore
使用的方法仅属于Action
类。