Java 我应该在if-else块中抛出异常吗?
代码如下:Java 我应该在if-else块中抛出异常吗?,java,if-statement,exception,throw,Java,If Statement,Exception,Throw,代码如下: public Response getABC(Request request) throws Exception { Response res = new Response(); try { if (request.someProperty == 1) { // business logic } else { throw new Exception("xxxx"); }
public Response getABC(Request request) throws Exception {
Response res = new Response();
try {
if (request.someProperty == 1) {
// business logic
} else {
throw new Exception("xxxx");
}
} catch (Exception e) {
res.setMessage(e.getMessage); // I think this is weird
}
return res;
}
这个程序运行良好。
我认为它应该重新设计,但是如何重新设计?除非catch块抛出不同的异常,否则在try块中抛出异常并立即捕获它是没有意义的 这样,您的代码将更有意义:
public Response getABC(Request request) {
Response res = new Response();
if (request.someProperty == 1) {
// business logic
} else {
res.setMessage("xxxx");
}
return res;
}
public Response getSomething(Request req){
if (req.someProperty == 1) {
Response res = new Response();
// logic
return res;
} else {
return ErrorResponse("error message"); // or throw RuntimeException here if you want to
}
}
只有当业务逻辑(当条件为true
时执行)可能引发异常时,才需要try-catch块
如果没有捕获异常(这意味着调用方必须处理它),则可以不使用else
子句:
public Response getABC(Request request) throws Exception {
if (request.someProperty != 1) {
throw new Exception("xxxx");
}
Response res = new Response();
// business logic
return res;
}
如果您正在从方法中抛出异常,那么为什么还要费心捕捉它呢?您可以返回带有“xxxx”消息的响应,也可以抛出一个异常以供此方法的调用方处理
public Response getABC(Request requst) {
Response res = new Response();
if(request.someProperty == 1){
//business logic
else{
res.setMessage("xxxx");
}
}
return res;
}
或
首先也是最重要的一点是,在重构工作方法时要更加小心,尤其是在执行手动重构时。也就是说,引入一个变量来保存
消息
可能是改变设计的一种方式:
public Response getABC(Request requst) throw Excetpions {
String message = "";
try{
if(request.someProperty == 1){
//business logic
else{
message = "xxxx";
}
}catch(Exception e){
message = e.getMessage();
}
Response res = new Response();
res.setMessage(message);
return res;
}
假设
业务逻辑
在成功时自行返回。故意抛出异常然后直接捕获异常时,似乎不正确,
它可以像这样重新设计,可以更改
抛出新异常(“xxxx”)代码>带有res.setMessage(“xxxx”)代码>,,
然后可以保留捕获异常部分,以便捕获业务逻辑内部可能发生的异常
public Response getABC(Request requst) {
Response res = new Response();
try{
if(request.someProperty == 1){
//business logic
else{
res.setMessage("xxxx");
}
}catch(Exception e){
res.setMessage(e.getMessage);
}
return res;
}
当您已经抛出选中的异常时,为什么要使用try/catch语句
<强>检查异常< /St>通常用于某些语言如C++或java,但不在像Kotlin这样的新语言中使用。我个人限制使用它
例如,我有这样一个类:
class ApiService{
Response getSomething() throw Exception();
}
它看起来干净易读,但破坏了异常处理机制的实用性。实际上,getSomething()?当ApiService的上游有人知道如何处理像这样的不可预测的或不可预防的错误时,这种方法就有效了。如果您真的知道如何处理它,那么继续使用下面的示例,否则,未检查异常就足够了
public Response getSomething(Request req) throws Exception{
if (req.someProperty == 1) {
Response res = new Response();
// logic
} else {
thows Exception("Some messages go here")
}
}
我鼓励大家这样做:
public Response getABC(Request request) {
Response res = new Response();
if (request.someProperty == 1) {
// business logic
} else {
res.setMessage("xxxx");
}
return res;
}
public Response getSomething(Request req){
if (req.someProperty == 1) {
Response res = new Response();
// logic
return res;
} else {
return ErrorResponse("error message"); // or throw RuntimeException here if you want to
}
}
要了解更多信息,我前面提到的Kotlin
由于许多原因不支持检查异常
以下是由StringBuilder
类实现的JDK
接口示例:
Appendable append(CharSequence csq) throws IOException;
这个签名写了什么?它说每当我向某个东西(一个StringBuilder
、某种日志、控制台等)附加一个字符串时,我必须捕获那些IOExceptions
。为什么?因为它可能正在执行IO
(Writer还实现了可追加的
)…所以它会导致到处都是这种代码:
try {
log.append(message)
}
catch (IOException e) {
// Must be safe
}
这是不好的,请参阅有效Java,第3版,第77项:不要忽略异常
请看以下链接:
- (罗德·沃尔德霍夫)
- (安德斯·海尔斯伯格)
异常机制有三个目的:
- 立即禁用正常程序流并返回调用堆栈,直到找到合适的catch块
- 以异常类型、消息和可选附加字段的形式提供上下文,catch块代码可以使用这些字段来确定操作过程
- 一个堆栈跟踪,供程序员查看以进行取证分析。(这件衣服过去制作成本很高)
这是一个机制需要具备的许多功能。为了让程序尽可能的简单,为了将来的维护人员,我们应该只在必要时使用这种机制
在您的示例代码中,我希望任何
throw
语句都是一个非常严重的事件,表明出现了问题,并且代码应该在某个地方处理这种紧急情况。在继续阅读程序的其余部分之前,我需要了解出了什么问题以及问题的严重程度。在这里,这只是一根线的奇特回归,我会搔搔头想“为什么这是必要的?”而额外的努力本可以花得更好
所以这段代码并没有它能做到的那么好,但是我只会在你有时间做一个完整测试的情况下修改它。更改程序流程可能会引入微妙的错误,如果您需要修复任何问题,您需要重新考虑这些更改。我认为您可能错过了尝试/捕获的要点。代码使用异常系统向调用方冒泡任何异常消息。这可能深入到嵌套调用堆栈中——而不仅仅是您正在查看的“抛出”调用堆栈
换句话说,示例代码中的“throws”声明利用这种机制向客户机传递消息,但它几乎肯定不是try/catch的主要预期用户。(这也是一种草率、有点廉价的传递信息的方式——它可能会导致混乱)
无论如何,这个返回值不是一个好主意,因为异常通常没有消息,可以重新包装。。。不过总比什么都没有好。异常消息并不是实现这一点的最佳工具,但像这样在高层处理异常仍然是一个好主意
我的观点是,如果重构此代码,请务必查找可能在代码库中的任何位置(至少在消息处理过程中调用的任何位置)抛出的运行时异常,即使这样,您也应该将catch/return消息作为catch-all保留,以防意外出现运行时异常。您不必将错误“Message”作为响应的消息返回——它可以是一些俏皮的“我们此时无法处理您的请求”,但一定要转储堆栈