为什么调用Exception Constructor而不是IOException构造函数?

时间:2015-12-22 15:09:13

标签: java overloading

下面是一个名为 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. 当异常不为null且 IOException 的实例时,系统将调用第一个构造函数异常构造函数,而不是 IOException构造函数
  3. 是什么原因?

1 个答案:

答案 0 :(得分:1)

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

null案例很有趣。当它无法确定对象输入类型时,这只是java解析到最具体的构造函数。

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

a_struct

另一种选择是分别显式捕获IOException,因此java将知道要调用的方法。

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

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