是否可以告诉编译器方法总是抛出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(); } }