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
相关产品推荐
相关产品推荐

