Bukkit插件跨文件调用非static方法loadHeadTextures失效求助
解决Bukkit插件跨文件调用非static方法无效的问题
问题根源
你的代码存在两个核心问题:
- 调用顺序错误:主类
Grillade的onEnable方法里,先调用AnvilListener的loadHeadTextures,再执行checkFiles创建heads.json文件。此时调用loadHeadTextures时文件还未生成,方法触发if (!jsonFile.exists())直接返回,没有加载任何数据。 - 重复加载冗余:
AnvilListener的事件处理方法中每次触发都调用loadHeadTextures,既浪费资源,也掩盖了主类调用无效的问题——事件触发时插件已完成初始化,文件已存在,所以能正常加载。
修复方案
1. 调整主类调用顺序
优先执行文件检查创建逻辑,确保heads.json存在后再加载纹理数据:
@Override public void onEnable() { instance = this; checkFiles(); // 先创建必要文件 AnvilListener anvilListener = new AnvilListener(); anvilListener.loadHeadTextures(); // 此时文件已存在,可正常加载 getServer().getPluginManager().registerEvents(anvilListener, this); getLogger().info("Grillade Plugin Operational!"); }
2. 移除事件中的重复加载
事件处理无需每次重新加载纹理,只保留初始化阶段的一次加载即可:
@EventHandler public void onAnvilPrepare(PrepareAnvilEvent event) { // 移除此处的loadHeadTextures调用 AnvilInventory anvilInventory = event.getInventory(); ItemStack[] contents = anvilInventory.getContents(); ItemStack firstInput = contents[0]; ItemStack secondInput = contents[1]; String renameText = event.getInventory().getRenameText(); List<Material> classicHeads = new ArrayList<>(); classicHeads.add(Material.CREEPER_HEAD); classicHeads.add(Material.SKELETON_SKULL); classicHeads.add(Material.ZOMBIE_HEAD); if (firstInput != null && secondInput == null && classicHeads.contains(firstInput.getType()) && renameText != null && headTextures.containsKey(renameText)) { String texture = headTextures.get(renameText); ItemStack customHead = createCustomHead(texture, renameText); event.setResult(customHead); } }
3. 优化纹理加载方法(可选)
如果后续需要支持热重载纹理,可在加载前清空旧数据,避免重复键值:
public void loadHeadTextures() { File jsonFile = new File(Grillade.getInstance().getDataFolder(), "heads.json"); Bukkit.broadcastMessage("正在加载头颅纹理"); if (!jsonFile.exists()) { return; } headTextures.clear(); // 清空旧数据,防止重复加载 try { FileReader reader = new FileReader(jsonFile); JsonElement jsonElement = JsonParser.parseReader(reader); JsonObject jsonObject = jsonElement.getAsJsonObject(); JsonArray headsArray = jsonObject.getAsJsonArray("heads"); for (JsonElement headElement : headsArray) { JsonObject headObject = headElement.getAsJsonObject(); String name = headObject.get("name").getAsString(); String texture = headObject.get("texture").getAsString(); headTextures.put(name, texture); } reader.close(); } catch (IOException e) { e.printStackTrace(); } }
验证效果
修改后,插件启用时会先创建heads.json(若不存在),再加载纹理数据,事件处理时直接使用已加载的headTextures映射,既解决了主类调用无效的问题,也提升了事件处理效率。
内容的提问来源于stack exchange,提问作者Zote
相关产品推荐
相关产品推荐

