递归方法的 StackOverflowError
StackOverflowError on recursive method
我在使用递归方法时遇到 WhosebugError。我在 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)
收到错误,如果 spawn 已经有玩家,它会自行调用。
看起来 s.hasPlayer()
总是正确的,因此:
if(s.hasPlayer()){
spawnPlayer(p);
}
在 spawnPlayer(Player)
方法内部执行,因此导致该方法无限地 运行,导致 WhosebugError
.
要解决此问题,您可以在调用 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...
}
}
我不确定,但从逻辑上讲我认为你想要:
if (!s.hasPlayer()) {
spawnPlayer(p);
注意!.
但总的来说,在 minecraft 中使用递归函数时要格外小心 :) 有一次我写了一个将树变成原木的函数,但它最终在树叶上递归——爆炸非常壮观——消失了整个阿甘,因为 activity.
杀了我的客户
我在使用递归方法时遇到 WhosebugError。我在 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)
收到错误,如果 spawn 已经有玩家,它会自行调用。
看起来 s.hasPlayer()
总是正确的,因此:
if(s.hasPlayer()){
spawnPlayer(p);
}
在 spawnPlayer(Player)
方法内部执行,因此导致该方法无限地 运行,导致 WhosebugError
.
要解决此问题,您可以在调用 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...
}
}
我不确定,但从逻辑上讲我认为你想要:
if (!s.hasPlayer()) {
spawnPlayer(p);
注意!.
但总的来说,在 minecraft 中使用递归函数时要格外小心 :) 有一次我写了一个将树变成原木的函数,但它最终在树叶上递归——爆炸非常壮观——消失了整个阿甘,因为 activity.
杀了我的客户