我有一个问题,我无法在一个全新的项目上重现;它是在针对Spigot 1.8.8-R0.1构建的Bukkit插件上发生的。
我正在开发一个命令框架。 有两种类型的命令:只能由玩家运行的命令......
private Map<Command, PlayerCommand> playerCommands = new HashMap<>();
public interface PlayerCommand {
void run(Player sender, String[] args);
}
......以及可能由控制台运行的那些。
private Map<Command, GlobalCommand> globalCommands = new HashMap<>();
public interface GlobalCommand {
void run(CommandSender sender, String[] args);
}
要注册命令,我已经实现了3种方法:
HashMap
。public void registerCommand(String name, PlayerCommand executor) {
Command command = registerCommand(name);
// 2
playerCommands.put(command, executor);
}
public void registerCommand(String name, GlobalCommand executor) {
Command command = registerCommand(name);
// 2'
globalCommands.put(command, executor);
}
CommandExecutor
属性设置为当前实例(稍后将处理它们,将工作委托给从地图中获取的特定自定义执行程序) )。private Command registerCommand(String name) {
PluginCommand command = plugin.getCommand(name);
if (command.getExecutor() == this) {
throw new CommandAlreadyRegisteredException("The '" + name + "' command has been already registered");
}
// 1
command.setExecutor(this);
return command;
}
您可能已经注意到,客户端不应该多次注册相同的命令。
为了达到这个目的,我知道我可以要求已经包含命令的地图,但这将是两个操作,同时用==
运算符检查执行程序(它必须是这个例子,不只是equals()
)只是一个。
所以,对于错误的情况,我决定抛出一个未经检查的异常:
public class CommandAlreadyRegisteredException extends RuntimeException {
private static final long serialVersionUID = 1L;
protected CommandAlreadyRegisteredException(String message) {
super(message);
}
}
这就是重点:我期望抛出异常将在抛出它的方法中返回,并在上层调用方法中返回。也就是说,第1,2和2点&#39;在这种情况下永远不应该执行。 但他们确实被执行了! 这怎么可能?你能重现吗?为什么会这样?
我知道我可以在私有方法中返回null
,但是客户端不会知道已经注册的命令。
答案 0 :(得分:1)
首次尝试注册命令:
第二次尝试:
this
视为其执行者。检查通行证,抛出异常。如果你想要的是阻止它被同一执行者注册两次,那么绝对不需要例外:
private Command registerCommand(String name) {
PluginCommand command = plugin.getCommand(name);
if (command.getExecutor() != this) {
command.setExecutor(this);
}
return command;
}
答案 1 :(得分:0)
没有错误。
为了调试,我在抛出异常后添加了一些System.out.println()
。
我正好打印那些断点。
没关系,因为这是第一次被允许注册,但出于某种原因,我认为它们是由第二次引起的...我不知道为什么。
答案 2 :(得分:-3)
您需要从Exception
而不是RuntimeException
扩展自定义异常类,然后才会对其进行检查,之后您可以在需要该异常的任何地方使用代码throw new YourException()
被抛出。