无界通配符无法强转为List<Game>类型,访问方法时抛出异常
问题根源
@SuppressWarnings("unchecked")的作用仅仅是关闭编译期的泛型类型检查警告,不会在运行时做任何实际的类型校验。
Java泛型基于编译期擦除实现:你把List<?>强转为List<GameImpl>时,运行时只会校验这个对象是不是List类型,完全不会检查列表内的元素类型。等你后续调用games2的方法访问元素时,JVM才会尝试把元素转成GameImpl,如果列表里实际存的不是GameImpl类型的对象,就会直接抛出ClassCastException。
你现在遇到异常,本质是fr.readFile()读取出的列表里的元素实际类型和GameImpl不匹配,单纯靠强制类型转换+压制警告解决不了根本问题。
修复方法
- 不要直接强转整个列表、跳过编译期检查。先校验读取结果的整体格式,再逐个校验列表内的元素类型,过滤掉不符合要求的内容,再组装成目标类型的列表。
- 优先检查文件写入逻辑,确认写入文件时存储的确实是
List<GameImpl>类型的数据,从序列化源头保证类型一致,避免读取出错。
参考实现代码:
@Override public void initialize(URL location, ResourceBundle resources) { try { Object rawReadResult = fr.readFile(); // 先校验读取结果是不是列表 if (!(rawReadResult instanceof List<?> rawList)) { throw new RuntimeException("文件内容格式错误,不是预期的列表结构"); } List<GameImpl> validGames = new ArrayList<>(); for (Object element : rawList) { // 逐个校验元素类型 if (element instanceof GameImpl gameItem) { validGames.add(gameItem); } else { // 可按需打印日志处理非法元素 System.out.println("跳过类型不匹配的元素:" + element); } } // 后续直接使用validGames即可,不会出现类型转换异常 this.games = validGames; } catch (IOException e) { System.out.println("文件读取异常"); throw new RuntimeException(e); } }
提示:如果遍历发现所有元素都不是
GameImpl类型,基本可以确定是文件写入逻辑存错了数据类型,优先排查写文件的代码,确认序列化的对象类型和反序列化的目标类型一致。
内容的提问来源于stack exchange,提问作者Andrea Zavatta
相关产品推荐
相关产品推荐

