为何强制转换List时出现类型安全警告且触发InventoryOpenEvent报错?
问题解答
一、类型转换警告的原因与解决办法
原因
ConfigurationSection.getList(String)方法的返回值是List<?>,即元素类型不确定的列表。直接强制转换为List<ItemStack>时,编译器无法在编译阶段验证列表中所有元素确实都是ItemStack类型,因此会抛出「未经检查的转换」警告——运行时如果列表中存在非ItemStack的元素,会触发ClassCastException。
解决办法
避免直接强制转换,通过逐个检查元素类型保证类型安全,同时消除警告:
private void loadGlobalChest() { ConfigurationSection inventorySection = items.getConfigurationSection("inventory"); if (inventorySection != null) { List<?> rawItems = inventorySection.getList("items"); if (rawItems != null) { List<ItemStack> itemStacks = new ArrayList<>(); for (Object obj : rawItems) { if (obj instanceof ItemStack) { itemStacks.add((ItemStack) obj); } // 可选:添加日志记录非法元素,便于排查问题 // else { Bukkit.getLogger().warning("发现非ItemStack类型的物品:" + obj); } } globalChestInventory.setContents(itemStacks.toArray(ItemStack[]::new)); } else { // 列表为null时,清空箱子初始化 globalChestInventory.clear(); } } }
若使用的Bukkit版本支持,也可直接用带类型参数的重载方法简化代码:
List<ItemStack> itemStacks = inventorySection.getList("items", ItemStack.class); if (itemStacks != null) { globalChestInventory.setContents(itemStacks.toArray(ItemStack[]::new)); }
二、getList返回null导致的报错问题
原因
当箱子内没有物品时,配置文件中的items节点可能不存在,或被设置为null;另外若保存物品时直接将空格子(null)存入列表,也可能引发加载异常。调用getList("items")返回null后直接执行toArray(),会触发NullPointerException,进而导致InventoryOpenEvent无法正常处理。
解决办法
- 加载时严格判空:除检查
inventorySection是否为null,还要校验getList的返回值,为空时初始化空箱子(如上述代码所示)。 - 优化保存逻辑:保存箱子物品时,确保空箱子也存入空列表而非
null;同时可过滤空格子的null值,避免配置文件中出现大量无效值:
// 保存箱子物品的示例代码 public void saveGlobalChest() { ConfigurationSection inventorySection = items.createSection("inventory"); List<ItemStack> itemList = new ArrayList<>(); for (ItemStack item : globalChestInventory.getContents()) { if (item != null) { itemList.add(item); } } inventorySection.set("items", itemList); // 保存配置文件到本地 try { items.save(new File("plugins/你的插件名/config.yml")); } catch (IOException e) { e.printStackTrace(); } }
这样即使箱子全空,配置文件中items节点也会是一个空列表,加载时getList不会返回null。
内容的提问来源于stack exchange,提问作者GalliardDev
相关产品推荐
相关产品推荐

