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

Spigot插件中HashMap已设值却返回0的技术求助

解决Spigot插件Leaping类中HashMap值退出潜行后返回0的问题

作为经常帮人排查Spigot插件问题的开发者,这种情况我遇到过不少,大概率是逻辑细节处理失误或者变量作用域出了问题,咱们一步步拆解:

1. 先查退出潜行的事件逻辑

你说潜行时charge能正常增长,那肯定是在PlayerToggleSneakEvent这类事件里做了增长处理,但退出潜行(也就是event.isSneaking()返回false的时候),是不是不小心加了重置charge的代码?比如:

@EventHandler
public void onSneakToggle(PlayerToggleSneakEvent event) {
    Player player = event.getPlayer();
    if (event.isSneaking()) {
        // 正常增长charge的逻辑
        int currentCharge = chargeMap.getOrDefault(player, 0);
        chargeMap.put(player, currentCharge + 1);
    } else {
        // 这里是不是写了 chargeMap.put(player, 0); ?
        // 如果是,退出潜行就会直接把值清零,这就是问题根源!
    }
}

如果是这种情况,把退出潜行时不必要的重置代码删掉就行,或者改成你真正需要的逻辑(比如只在玩家完成跳跃后再重置,而不是一退出潜行就重置)。

2. 确认HashMap的作用域是否正确

有没有可能你的HashMap<Player, Integer> chargeMap是方法内的局部变量?比如这样:

public void handleSneak() {
    HashMap<Player, Integer> chargeMap = new HashMap<>();
    // 这里操作chargeMap,方法执行完后这个map就被回收了
}

如果是这样,每次操作的都是新创建的map,之前保存的charge自然会丢失,查询就返回0。你需要把它改成类的成员变量,保证整个插件生命周期内都能复用:

public class Leaping extends JavaPlugin {
    // 把map定义为类的成员变量
    private HashMap<Player, Integer> chargeMap = new HashMap<>();
    
    @EventHandler
    public void onSneakToggle(PlayerToggleSneakEvent event) {
        // 直接操作这个成员变量
        Player player = event.getPlayer();
        if (event.isSneaking()) {
            chargeMap.put(player, chargeMap.getOrDefault(player, 0) + 1);
        }
    }
}

3. 排查其他可能重置charge的逻辑

比如玩家跳跃事件(PlayerJumpEvent)、移动事件里,是不是在退出潜行后触发了某个逻辑把charge设为0?你可以在所有修改chargeMap的地方加个日志打印,追踪值的变化:

// 增长时打印
int newCharge = chargeMap.getOrDefault(player, 0) + 1;
chargeMap.put(player, newCharge);
getLogger().info(player.getName() + "的charge更新为:" + newCharge);

// 重置时也打印
chargeMap.put(player, 0);
getLogger().info(player.getName() + "的charge被重置为0");

这样就能清楚看到什么时候charge被改成0,快速定位问题代码。

4. 确认Player对象的一致性

虽然Spigot里Player对象是单例的,但也要避免用错对象,比如不要通过玩家名字重新获取Player(理论上没问题,但可能出现意外):

// 不推荐:用名字获取的Player可能和事件中的对象引用不一致(概率极低,但要避免)
Player player = Bukkit.getPlayer(event.getPlayer().getName());

直接使用event.getPlayer()获取的对象操作map就好。


先从这几个方向排查,最常见的就是前两种情况。如果还是解决不了,可以把相关的代码片段贴出来,我再帮你细看~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 08:05:24