Java 自定义未检查异常不存在';t使抛出和调用方方法返回
我有一个问题,我无法复制一个全新的项目;这发生在Bukkit插件上,它是根据Spigot 1.8.8-R0.1构建的 我正在开发一个命令框架。 有两种类型的命令:只能由玩家运行的命令Java 自定义未检查异常不存在';t使抛出和调用方方法返回,java,exception,bukkit,Java,Exception,Bukkit,我有一个问题,我无法复制一个全新的项目;这发生在Bukkit插件上,它是根据Spigot 1.8.8-R0.1构建的 我正在开发一个命令框架。 有两种类型的命令:只能由玩家运行的命令 private Map<Command, PlayerCommand> playerCommands = new HashMap<>(); …以及可能由控制台运行的 private Map<Command, GlobalCommand> globalCommands = new
private Map<Command, PlayerCommand> playerCommands = new HashMap<>();
…以及可能由控制台运行的
private Map<Command, GlobalCommand> globalCommands = new HashMap<>();
为了注册该命令,我实现了3种方法:
- 每个命令类型有2个公共方法,它们应该将每个自定义执行器添加到其特定的
HashMap
- 1个专用方法,用于它们共同的逻辑,即将它们的Bukkit的
属性设置为当前实例(稍后将处理它们,将工作委托给从映射中获取的特定自定义执行器)CommandExecutor
==
操作符检查执行器(必须是这个实例,而不仅仅是equals()
)只是一个
因此,对于错误的情况,我决定抛出一个未检查的异常:
public class CommandAlreadyRegisteredException extends RuntimeException {
private static final long serialVersionUID = 1L;
protected CommandAlreadyRegisteredException(String message) {
super(message);
}
}
private Command registerCommand(String name) {
PluginCommand command = plugin.getCommand(name);
if (command.getExecutor() != this) {
command.setExecutor(this);
}
return command;
}
关键是:我希望抛出异常会在抛出异常的方法中返回,在上面的调用方方法中返回。也就是说,在这种情况下,第1点、第2点和第2点’不应执行。
但他们确实会被处决强>
这怎么可能?你能复制它吗?为什么会发生这种情况
我知道我可以在私有方法中返回
null
,但是这样客户端就不会知道命令已经注册了。您需要从exception
扩展自定义异常类,而不是RuntimeException
,因为这样会被检查,然后您可以使用代码抛出新的异常()
需要抛出该异常的任何地方。您需要从exception
而不是RuntimeException
扩展您的自定义异常类,然后将对其进行检查,然后可以使用代码抛出新的YourException()
需要抛出该异常的任何位置。首先尝试注册命令:
- 您可以从插件获取命令
- 该命令没有执行器,因此检查失败
- 然后你设定遗嘱执行人
- 您可以从插件获取命令它与您第一次得到的命令是同一个对象。
- 它仍然将此视为其执行者。检查通过,抛出异常
public class CommandAlreadyRegisteredException extends RuntimeException {
private static final long serialVersionUID = 1L;
protected CommandAlreadyRegisteredException(String message) {
super(message);
}
}
private Command registerCommand(String name) {
PluginCommand command = plugin.getCommand(name);
if (command.getExecutor() != this) {
command.setExecutor(this);
}
return command;
}
首次尝试注册命令:
- 您可以从插件获取命令
- 该命令没有执行器,因此检查失败
- 然后你设定遗嘱执行人
- 您可以从插件获取命令它与您第一次得到的命令是同一个对象。
- 它仍然将此视为其执行者。检查通过,抛出异常
public class CommandAlreadyRegisteredException extends RuntimeException {
private static final long serialVersionUID = 1L;
protected CommandAlreadyRegisteredException(String message) {
super(message);
}
}
private Command registerCommand(String name) {
PluginCommand command = plugin.getCommand(name);
if (command.getExecutor() != this) {
command.setExecutor(this);
}
return command;
}
没有bug
为了调试,我在抛出异常后添加了一些System.out.println()
。
我只打印了一次断点。
没关系,因为这是第一次被允许注册,但出于某种原因,我认为这是第二次注册造成的。。。我不知道为什么
没有错误
为了调试,我在抛出异常后添加了一些System.out.println()
。
我只打印了一次断点。
没关系,因为这是第一次被允许注册,但出于某种原因,我认为这是第二次注册造成的。。。我不知道为什么
我不想每次需要注册命令时都使用try-catch块。你是说未检查的异常不会阻止代码执行吗?所有异常都能够阻止程序的进一步执行。但是要抛出自定义异常,您必须显式地这样做,因为Java运行时无法知道您希望何时抛出异常,因此您必须使用我在代码中没有看到的throw关键字。从Exception类进行扩展更自然,因为这样更安全,因为异常将被检查,而RuntimeException的子类在第二个代码块第21行未被检查。这与是否检查异常无关,但是为什么运行时选择不让抛出的未经检查的异常阻止执行。很抱歉,我现在意识到您实际上已经显式抛出了异常。你检查过情况是否真的通过了吗。我的意思是,如果条件失败或通过,我不想每次需要注册命令时都使用try-catch块。你是说未检查的异常不会阻止代码执行吗?所有异常都能够阻止程序的进一步执行。但是要抛出自定义异常,您必须显式地这样做,因为Java运行时无法知道您希望何时抛出异常,因此您必须使用我在代码中没有看到的throw关键字。从Exception类进行扩展更自然,因为这样更安全,因为异常将被检查,而RuntimeException的子类在第二个代码块第21行被取消检查。这不是是否检查异常的问题,而是为什么运行时选择不让抛出的异常取消检查
private Command registerCommand(String name) {
PluginCommand command = plugin.getCommand(name);
if (command.getExecutor() != this) {
command.setExecutor(this);
}
return command;
}