java - 递归方法上的 StackOverflowError

标签 java recursion bukkit stack-overflow

使用递归方法时出现 StackOverflowError。我正在 Spigot API 之上进行构建。

这是我的方法:

private Location spawnPlayer(Player p) {
    int r = new Random().nextInt(ServerManager.getInstance().getServer(p).getSpawns().size());
    final Spawn s = ServerManager.getInstance().getServer(p).getSpawns().get(r);

    if (s.hasPlayer()) {
        spawnPlayer(p);
    } else {
        s.setPlayer(p);

        Bukkit.getServer().getScheduler().scheduleSyncRepeatingTask(Arsenal.p, new Runnable() {
            public void run() {
                spawnClear--;

                if (spawnClear == 0) {
                    s.setPlayer(null);
                }
            }
        }, 0L, 20L);
    }
    return s.getLocation();
}

我在 spawnPlayer(p) 处收到错误,如果生成点已经有玩家,它会调用自身。

最佳答案

看起来 s.hasPlayer() 始终为 true,因此:

if(s.hasPlayer()){
    spawnPlayer(p);
}

spawnPlayer(Player) 方法内部执行,这会导致该方法无限运行,从而导致 StackOverflowError .

要解决此问题,您可以在调用 spawnPlayer(p) 之前等待:

if(s.hasPlayer()){
    long timeToWait = 20L;//set the time to wait to 20 ticks (1 second)
    Bukkit.getServer().getScheduler().runTaskLater(Arsenal.p, new Runnable(){
        public void run(){
            spawnPlayer(p);
        }
    },timeToWait);
}

那么,您的代码可能如下所示:

private Location spawnPlayer(Player p) {
    int r = new Random().nextInt(ServerManager.getInstance().getServer(p).getSpawns().size());
    final Spawn s = ServerManager.getInstance().getServer(p).getSpawns().get(r);

    if(s.hasPlayer()){
        long timeToWait = 20L;//set the time to wait to 20 ticks (1 second)
        Bukkit.getServer().getScheduler().runTaskLater(Arsenal.p, new Runnable(){
            public void run(){
                spawnPlayer(p);
            }
         },timeToWait);
    }
    else{
        s.setPlayer(p);

        Bukkit.getServer().getScheduler().scheduleSyncRepeatingTask(Arsenal.p, new Runnable() {
            public void run() {
                spawnClear--;

                if (spawnClear == 0) {
                    s.setPlayer(null);
                }
            }
        }, 0L, 20L);
    }
    return s.getLocation();
}

另一个修复方法是使 s.hasPlayer() 并不总是正确,例如,通过使用 ArrayList确保玩家尚未生成:

List<String> spawned = new ArrayList<String>();

private Location spawnPlayer(Player p){
   int r = new Random().nextInt(ServerManager.getInstance().getServer(p).getSpawns().size());
   final Spawn s = ServerManager.getInstance().getServer(p).getSpawns().get(r);

   if(s.hasPlayer() && !spawned.contains(p.getName()){
      spawned.add(p.getName());
      spawnPlayer(p);
   }
   else{
     //the rest of your code...
   }
}

关于java - 递归方法上的 StackOverflowError,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28797398/

相关文章:

java - 在 ViewPager 中选择要开始的 fragment - Android

java - 不使用默认构造函数反序列化 JSON

recursion - 递归测试文件夹中的所有flac文件

javascript - 从 JS 对象中删除所有空字符串、空对象和空数组

java - 树的递归种群

java - 如何监控 headless java进程?

Javac 1.8.0_25 存在已知错误 - 如何使用不同版本?

java - Bukkit/Java 可定制的百分比机会

java - 我的世界财富 block

java - 使用 maven 导出的 jar 文件中包含 jar 文件和依赖项