开发者社区 问答 正文

List <T>类型中的方法add(T)不适用于自变量

我在堆栈溢出中搜索了此错误,但是没有一个设计和我一样。对于术语的建议,以帮助找到类似下面的示例代码的类似主题,将不胜感激。

这是一个演示该错误的简单测试用例:

import java.util.List;

public class SimpleTest {

    abstract class AbsTask<T>
    {

    }

    abstract class AbsQueue<T extends AbsTask<?>>
    {
        private List<T> lst;

        public void addSpecialItem()
        {
            lst.add(new SpecialItem()); // Error occurs here
        }



    }

    class SpecialItem extends AbsTask<Void>
    {

    }

}

我想添加到我的抽象类的方法AbsQueue称为addSpecialItem,这将插入SpecialItem类到列表中的通用列表T中基本上是列表AbsTask。

这是错误: The method add(T) in the type List is not applicable for the arguments (SimpleTest.SpecialItem)

如果我输入case如下所示,我可以解决此错误:

lst.add((T)new SpecialItem());

是否有处理这种不类型转换的方式new SpecialItem()来T?

展开
收起
垚tutu 2019-12-04 16:53:47 703 分享 版权
阿里云 AI 助理回答

在Java中,泛型是为了提供类型安全和编译时检查而设计的。当你声明一个泛型类如AbsQueue<T>时,你期望T是一个特定的类型或者满足某种约束(例如继承自某个类或实现某个接口)。在你的例子中,你希望T是AbsTask或其子类。

然而,直接在泛型类内部尝试向泛型类型的列表添加具体类型对象(如SpecialItem)而不进行显式类型转换,会导致编译错误,因为编译器无法确保这个操作对所有可能的T都是类型安全的。

解决这个问题的一个方法是你已经提到的,即进行显式的类型转换,但这通常被视为一种不理想的解决方案,因为它可能会抑制潜在的类型安全警告,并且如果T不是SpecialItem的超类,运行时会抛出ClassCastException

更好的做法是利用泛型的边界限制来确保只有当T是AbsTask或其子类时,AbsQueue才能被实例化。然后,你可以安全地将SpecialItem添加到列表中,因为你知道T至少是AbsTask。这里是如何修改你的代码:

import java.util.List;
import java.util.ArrayList;

public class SimpleTest {

    abstract class AbsTask {}

    abstract class AbsQueue<T extends AbsTask> {
        private List<T> lst = new ArrayList<>();

        public void addSpecialItem() {
            lst.add(new SpecialItem()); // Now this is safe because T must be AbsTask or its subclass
        }
    }

    class SpecialItem extends AbsTask {}
}

在这个修改后的版本中,AbsQueue定义为AbsQueue<T extends AbsTask>,这意味着T必须是AbsTask或其子类。这样,在addSpecialItem方法中添加SpecialItem对象就是类型安全的,不需要显式类型转换,因为现在可以确定任何AbsQueue实例的lst列表能够接受AbsTask及其子类的实例。

有帮助
无帮助
AI 助理回答生成答案可能存在不准确,仅供参考
0 条回答
写回答
取消 提交回答
问答分类:
问答地址: