You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java如何创建仅存储继承controlBase类实例的ArrayList

问题根源

你使用ArrayList<? extends controlBase>声明列表时用了上界通配符,根据Java泛型的安全规则,这类声明了上界通配符的集合不允许写入任何非null元素:编译器无法确认该列表实际要求存储的是controlBase的哪一个具体子类型,为了避免类型不匹配的运行时错误,会直接拦截所有add操作,这就是你所有添加逻辑都编译报错的核心原因。

另外你写的registerController方法本身还有逻辑错误:参数定义为Class<T>是类的字节码对象,不是controlBase的实例,本身就不能直接存入存储控制器实例的列表。

正确写法

你需要存储所有controlBase及其子类的实例,根本不需要使用通配符,直接将列表泛型声明为基类类型即可,Java的多态特性天然支持将子类实例放入基类类型的集合:

// 列表的正确声明方式
private ArrayList<controlBase> controllers = new ArrayList<>();

如果你的注册方法是直接接收控制器实例,写法如下,所有controlBase子类的实例都可以正常传入:

public void registerController(controlBase controller) {
    controllers.add(controller);
}

如果你的注册方法确实是传入控制器类的字节码、需要在方法内部反射创建实例再存入,需要补全实例化逻辑:

public <T extends controlBase> void registerController(Class<T> controllerClass) {
    try {
        // 调用无参构造创建实例,可根据你的实际构造方法传参
        T controllerInstance = controllerClass.getDeclaredConstructor().newInstance();
        controllers.add(controllerInstance);
    } catch (Exception e) {
        // 处理反射实例化相关异常,比如无参构造不存在、访问权限不足等
        throw new IllegalArgumentException("控制器实例化失败", e);
    }
}

修正后以下所有添加操作都可以正常执行,不会出现编译错误:

controllers.add(new controlBase());
controllers.add(new joystick()); // joystick为controlBase子类,符合类型要求

小提示:Java命名规范要求类名使用大驼峰格式,controlBase、joystick这类小写开头的类名不符合规范,建议调整为ControlBase、Joystick,避免后续出现不必要的兼容问题。

内容的提问来源于stack exchange,提问作者Brendan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 00:03:34