Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/383.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java中忽略泛型_Java_Generics - Fatal编程技术网

Java中忽略泛型

Java中忽略泛型,java,generics,Java,Generics,所以我有以下Java代码: public <A extends Action> List<A> getActionsFor(Actor a) { List<A> theActions = super.getActionsFor(a); for (Action ac: a.getItemCarried().getActions()) { theActions.add(ac); } return theActio

所以我有以下Java代码:

public <A extends Action> List<A> getActionsFor(Actor a) {
    List<A> theActions = super.getActionsFor(a);

    for (Action ac: a.getItemCarried().getActions()) {
        theActions.add(ac);
    }

    return theActions;
}
public List getactions for(参与者a){
列出操作=super.getActions for(a);
对于(操作ac:a.getItemCarried().getActions()){
添加(ac);
}
返回动作;
}
出于某种原因,javac拒绝了.add(ac)声明add(A)不能应用于操作

我是不是丢了什么钥匙?我可以通过在两个包之间创建依赖项来解决这个问题,但我真的不想这样做

所有有问题的类都已正确导入,每个方法调用都有效,所以我真的不明白为什么它不能接受A扩展的类类型


如果您有任何建议,即使您不确定,我们也将不胜感激,因为我必须在接下来的6小时内修复此问题,否则我将需要创建依赖项。

您正在声明一个明确的
A
列表,如果您要接受所有子类,请在列表声明中指定:

List<? extends A> theActions = super.getActionsFor(a);

List在您的示例中,您没有指定什么是
A
,它是
Action
的子类。您想添加一个不允许的超类型
a
(一个
操作
)的实例。您需要强制转换到
A
(不安全,会发出警告),或者只返回
列表

我是不是丢了什么钥匙

A
是扩展动作的东西,
ac
也是扩展动作的东西。然而,这有点像设施

Yesterday I saw someone.
Someone is the President
Therefor, yesterday I was the President.
问题是编译器无法知道
A
Action
Action
的兼容子类

一个简单的解决办法是不要太具体。在此方法中使用
Action
而不是
A

public List<Action> getActionsFor(Actor a) {
    // this has to return a copy of the List or you will be modifying an original
    List<Action> theActions = super.getActionsFor(a);

    for (Action ac: a.getItemCarried().getActions()) {
        theActions.add(ac); // ac is an Action so all good.
    }

    return theActions;
}
public List getactions for(参与者a){
//这必须返回列表的副本,否则您将修改原始列表
列出操作=super.getActions for(a);
对于(操作ac:a.getItemCarried().getActions()){
theActions.add(ac);//ac是一个非常好的动作。
}
返回动作;
}
或者你可以做你所拥有的,但更复杂

public <A extends Action> List<A> getActionsFor(Actor<A> a) {
    List<A> theActions = super.getActionsFor(a);

    for (A ac: a.getItemCarried().getActions()) {
        theActions.add(ac); // ac is an A, so all good.
    }

    return theActions;
}
public List getactions for(参与者a){
列出操作=super.getActions for(a);
对于(A ac:A.getItemCarried().getActions()){
theActions.add(ac);//ac是A,所以一切都好。
}
返回动作;
}
如果将
用作泛型类型,则不能以类型安全的方式将元素添加到使用
a
键入的
列表中

原因是您不知道
A
的确切类型

假设您有两个子类
Action
ActionA
ActionB

现在完全可以这样写:

List<A> theActions = new ArrayList<ActionA>();

那么,我如何让它接受“行动”呢?”A“应该已经采取了任何类型的“Action”或从“Action”扩展而来的东西,不是吗?我已经把我的评论移到了一个答案上,并扩展了我要补充的一点:泛型类型没有你可能期望的那种超/子类关系。例如,
ArrayList
不是
ArrayList
的超类型。为什么?如果
ArrayList
ArrayList
的超类型,则可以执行
ArrayList list=new ArrayList()
,然后您可以将
编号
对象放入
列表
,这应该是一个
数组列表这不允许您添加(),只允许获取()啊,是的,您是对的。在这种情况下,我认为您的答案更正确。您提供的第二个解决方案返回完全相同的错误,但第一个解决方案确实有效。这真的让我很困惑,因为超级类中存在几乎相同的代码,引用不同的类,但具有相同的关系,并且在那里工作得很好。感谢您的帮助。@David第二种方法只有在
getActions()
返回
列表时才有效。
注意:
Actor
还有更多的更改要使其工作。
theActions.add(new Action()); // doesn't compile