使用递归方法时出现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)
收到错误,如果产生的玩家已有玩家,则会自行调用错误。
答案 0 :(得分:1)
看起来s.hasPlayer()
总是如此,如此:
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...
}
}
答案 1 :(得分:0)
我不确定,但逻辑上我认为你想要:
if (!s.hasPlayer()) {
spawnPlayer(p);
注意!。
一般情况下,在我的世界中使用递归功能需要很多照顾:)一旦我写了一个将树变成日志但它最终在树叶上递归 - 爆炸非常壮观 - 一扫而空由于所有的活动,福雷斯特和杀死了我的客户。