Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/335.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/ant/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 我应该在if-else块中抛出异常吗?_Java_If Statement_Exception_Throw - Fatal编程技术网

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”作为响应的消息返回——它可以是一些俏皮的“我们此时无法处理您的请求”,但一定要转储堆栈