Java Intellij空检查:无法访问的语句
这个问题类似于,但重点有所不同 我有一个函数,可以在try-catch块中加载磁盘上的文件。由于文件对程序至关重要,因此如果无法加载文件,它将终止:Java Intellij空检查:无法访问的语句,java,intellij-idea,null,Java,Intellij Idea,Null,这个问题类似于,但重点有所不同 我有一个函数,可以在try-catch块中加载磁盘上的文件。由于文件对程序至关重要,因此如果无法加载文件,它将终止: String loadSuperImportantFile() { try { // ... file loading code ... assert fileContent != null; return fileContent; } catch(IOException ex) {
String loadSuperImportantFile() {
try {
// ... file loading code ...
assert fileContent != null;
return fileContent;
} catch(IOException ex) {
System.err.println("Failed to load super important file. Please check path.");
System.exit(Codes.FAIL); // terminate the program
}
return null; // statement is unreachable
}
IntelliJ IDEA不承认此函数不可能返回null。因此,每当我使用返回字符串时,都会收到警告:
foo(loadSuperImportantFile()); // WARNING: Argument "loadSuperImportantFile()" might be null.
通过阅读我上面链接的问题,我相信可以使用方法契约告诉IntelliJ方法不能返回null。我尝试使用@Contract(“null->fail”)
装饰器,但警告并没有消失
有没有人知道如何使用方法契约或类似的方法,而不是外部检查空值,使警告在方法本身中消失?System.exit(Codes.FAIL)
在Java中不是终止语句(如return
或throw
)
在某些有线情况下,您可以想象,可以覆盖exit
方法(或模拟它),这样它就不会终止应用程序。然后将返回此null
对于简洁而健壮的应用程序,如果要终止该应用程序,请抛出一个可能会向上传播的异常。特别是,如果因为发生错误(无效路径)而要终止应用程序。更实际的做法是让应用程序自行消亡。为什么必须调用System.exit()代码>
PS:您还可以看到@Stephen C或@user31601的答案,这肯定会解决方法返回null
(因为它使用流控制语句-throw
)的问题,但我不建议使用该选项。在我看来,最好设计一个更好的结构,一个简洁的结构,不让这种情况发生——相反,允许它发生,然后在发生时抛出断言异常
PS2:你也可以像@yole建议的那样添加@NotNull
,但是,不要对不应该发生的事情做出反应,只是不要让它发生。并抛出(例如)抛出新的InvalidPathException()代码>
我的建议是:
String loadSuperImportantFile() {
try {
return fileContent;
} catch(IOException ex) {
throw new ImportantFileMissingException("Failed to load super important file. Please check path.");
}
}
class ImportantFileMissingException extends RuntimeException {}
系统退出(代码失败)
在Java中不是终止语句(如return
或throw
)
在某些有线情况下,您可以想象,可以覆盖exit
方法(或模拟它),这样它就不会终止应用程序。然后将返回此null
对于简洁而健壮的应用程序,如果要终止该应用程序,请抛出一个可能会向上传播的异常。特别是,如果因为发生错误(无效路径)而要终止应用程序。更实际的做法是让应用程序自行消亡。为什么必须调用System.exit()代码>
PS:您还可以看到@Stephen C或@user31601的答案,这肯定会解决方法返回null
(因为它使用流控制语句-throw
)的问题,但我不建议使用该选项。在我看来,最好设计一个更好的结构,一个简洁的结构,不让这种情况发生——相反,允许它发生,然后在发生时抛出断言异常
PS2:你也可以像@yole建议的那样添加@NotNull
,但是,不要对不应该发生的事情做出反应,只是不要让它发生。并抛出(例如)抛出新的InvalidPathException()代码>
我的建议是:
String loadSuperImportantFile() {
try {
return fileContent;
} catch(IOException ex) {
throw new ImportantFileMissingException("Failed to load super important file. Please check path.");
}
}
class ImportantFileMissingException extends RuntimeException {}
IntelliJ IDEA不承认此函数不可能返回null
IntelliJ只是遵循标准的Java可达性规则。这表示返回null代码>语句是可访问的
有人对如何使警告在方法本身中消失有想法吗
您可以将最后一条语句替换为:
throw new AssertionError("unreachable statement executed");
或者更好的是,将它放在System.exit(…)
调用之后
任何未经检查的异常都可以,但在我看来,AssertionError
是发生完全错误的最有力的指示。请注意,您需要显式抛出异常。使用断言
不足以避免需要返回
。。。因为断言检查可以关闭
从不执行的throw
语句的运行时开销最小,为零
另一个想法是返回一个伪非空值。在本例中,可以使用空字符串
将该方法注释为@NotNull
的问题在于,静态代码分析器(使用与IntelliJ相同的不完整逻辑)可能会标记该方法确实返回null
。如果您可以抑制该警告,那么也有可能某些框架会插入运行时检查null
。。。其中1)没有作用,2)可能无法优化
不幸的是,没有实用的方法来标记系统。退出时,会有一个注释,上面写着“此语句永远不会返回”。为什么?因为这是一个标准的方法,你不能改变它。。。没有入侵类库和(可能)破坏可移植性
要解决这个问题,您(我认为)所能做的最好的事情就是开发一个补丁并提交给Intellij维护人员。“理解”系统特殊行为的人。退出
最后,一般来说,库方法调用System.exit
是一个不好的主意,就像您的示例中那样。一个更好的方法是抛出一个定制的异常,您可以使用catc