繁体   English   中英

为什么调用异常构造函数而不是 IOException 构造函数?

[英]why Exception Constructor is called instead of IOException Constructor?

下面是一个名为AuthentificationResourceException的 java 类,它扩展了Exception并具有 2 个重载的构造函数。 为简单起见,当用户调用位于 Controller 类中的 verifyToken 方法时,将抛出此异常。

 public class AuthentificationResourceException extends Exception{

    // Exception constructor
    public AuthentificationResourceException(Exception cause, VerifyTokenResponse response) {
            handleException(response, "Exception verifyToken method");
        }

    // IOException constructor
    public AuthentificationResourceException(IOException cause, VerifyTokenResponse response) {
        handleException(response, "Probleme of reading / writting");
    }

    public void handleException(VerifyTokenResponse response, String messageException) {
        response.setValid(false);
        response.setCause(messageException);
    }

在控制器类中,我使用@ExceptionHandler 注解来管理 verifyToken 方法抛出的未处理异常:

@Controller
@RequestMapping(value = "/authentification", method = RequestMethod.POST, consumes = "application/json", produces = "application/json"){
public class AuthentificationRessource {



            @RequestMapping(value = "/verifyToken", method = RequestMethod.POST, consumes = "application/json", produces = "application/json")
            @ExceptionHandler({ AuthentificationResourceException.class })
            @ResponseBody
            public VerifyTokenResponse verifyToken(@RequestBody VerifyTokenRequest request)
                    throws AuthentificationResourceException {

                JWTVerifier verifier = new JWTVerifier("TOTO");
                VerifyTokenResponse response = new VerifyTokenResponse();

                try {
                    Map<String, Object> mapper = verifier.verify(request.getToken());
                    response.setMapper(mapper);
                    response.setValid(true);
                } catch (Exception e) {
                    // map exceptions with ExceptionHandler
                    throw new AuthentificationResourceException(e, response);
                }
                return response;
            }

}

当我使用 Junit 来测试 verifyToken 方法时,我遇到了一个问题:

  1. 当异常为 null 且类型为IOException 时,系统调用第二个构造函数IOException 构造函数
  2. 当异常不为空并且是IOException 的实例时,系统调用第一个构造函数Exception 构造函数而不是IOException 构造函数

是什么原因 ?

在 Java 中,重载方法是在编译时解析的。 所以在catch子句中,函数可以根据其编译时类型是任何异常,因此java将函数调用解析到第一个构造函数。

null 的情况很有趣。 这只是 java 在无法确定对象输入类型时解析为最具体的构造函数。

解决此问题的一种方法是运行时类型检查。

  public AuthentificationResourceException(Exception cause, VerifyTokenResponse response) {
      if (cause instanceof IOException) {
         handleException(response, "Problem reading / writing");
      } else {
         handleException(response, "Exception verifyToken method");
      }
  }

另一种选择是分别显式地捕获 IOException 以便 java 知道要调用什么方法。

try {
   ...
} catch(IOException e) {
   throw new AuthentificationResourceException(e, response);
} catch (Exception e) {
   throw new AuthentificationResourceException(e, response);
}

尝试在那里重载是一个有趣的想法,但不幸的是,java 类型系统不允许运行时重载。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM