是否可以告诉编译器方法总是抛出exception

一般来说,Java编译器不会传播方法“总是”抛出exception的信息,因此不会检测到所有代码路径都是完整的。

(这是因为Java编译器独立编译每个类)。

当你想写那样的东西时,这是一个问题。

public class ErrorContext { public void fatalISE(String message) { String context = "gather lots of information about the context of the error"; throw new IllegalStateException(context +": " + message); } } public class A { public MyObject myMethod() { if (allIsGood()) { return new MyObject(); } ErrorContext.fatalISE("all is not good"); } } 

(即,一种收集上下文信息的“断言助手”)。

因为编译器会抱怨myMethod并不总是返回MyObject。

据我所知,没有特定的注释来指示方法总是抛出。

一个简单的解决方法是让你的fatalISE方法不抛出exception,但只创建它:

 public class ErrorContext { public IllegalStateException fatalISE(String message) { String context = "gather lots of information about the context of the error"; return new IllegalStateException(context +": " + message); } } public class A { public MyObject myMethod() { if (allIsGood()) { return new MyObject(); } throw ErrorContext.fatalISE("all is not good"); } } 

这样编译器就会知道不要抱怨丢失的return 。 并且忘记使用throw是不太可能的,因为编译器通常会抱怨。

我使用的技巧是替换

 public void fatalISE(String message) { String context = "gather lots of information about the context of the error"; throw new IllegalStateException(context +": " + message); } 

 public  T fatalISE(String message) { String context = "gather lots of information about the context of the error"; throw new IllegalStateException(context +": " + message); } 

然后,在myMethod中,使用:

 public MyObject myMethod() { if (allIsGood()) { return new MyObject(); } return ErrorContext.fatalISE("all is not good"); } 

无论myMethod的返回类型如何,它都可以工作,包括原始类型。 你仍然可以在void方法中使用fatalISE ,只需不使用return关键字。

如何扭转if条件?

 public MyObject myMethod() { if (!allIsGood()) { ErrorContext.fatalISE("all is not good"); } return new MyObject(); } 

祝你好运!

 return null; 

在末尾。 (无论如何它永远不会到达那里,但是这应该做的编译器无声)

我刚刚遇到了这个用例,但是使用的方法应该总是抛出2种或更多类型的exception。

要使代码编译,您可以添加return null; 正如MouseEvent所说。

或者更好地使用throw new AssertionError()来替换它,以防止返回空值,提高可读性并确保如果有人修改checkAndAlwaysThrowException()它将继续始终抛出exception

 public Object myMehtod() throws ExceptionType1, ExceptionType2 { //.... checkAndAlwaysThrowException(); throw new AssertionError("checkAndAlwaysThrowException should have throw exception"); } public void checkAndAlwaysThrowException() throws ExceptionType1, ExceptionType2 { if (cond) { throw new ExceptionType1(); } else { throw new ExceptionType2(); } }