Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/320.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 为什么调用异常构造函数而不是IOException构造函数?_Java_Overloading - Fatal编程技术网

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

Java 为什么调用异常构造函数而不是IOException构造函数?,java,overloading,Java,Overloading,下面是一个名为AuthentificationResourceException的java类,它扩展了Exception并具有2个重载构造函数。 为简单起见,当用户调用位于控制器类中的verifyToken方法时,将引发此异常 public class AuthentificationResourceException extends Exception{ // Exception constructor public AuthentificationResourceExce

下面是一个名为AuthentificationResourceException的java类,它扩展了Exception并具有2个重载构造函数。 为简单起见,当用户调用位于控制器类中的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;
            }

}
@控制器
@RequestMapping(value=“/authentication”,method=RequestMethod.POST,consumes=“application/json”,products=“application/json”){
公共类AuthentificationRessource{
@RequestMapping(value=“/verifyToken”,method=RequestMethod.POST,consumes=“application/json”,products=“application/json”)
@ExceptionHandler({AuthentificationResourceException.class})
@应答器
公共VerifyTokenResponse verifyToken(@RequestBody VerifyTokenRequest请求)
抛出AuthentificationResourceException{
JWTVerifier verifier=新JWTVerifier(“TOTO”);
VerifyTokenResponse响应=新的VerifyTokenResponse();
试一试{
Map mapper=verifier.verify(request.getToken());
响应。设置映射器(映射器);
response.setValid(true);
}捕获(例外e){
//使用ExceptionHandler映射异常
抛出新的AuthentificationResourceException(e,响应);
}
返回响应;
}
}
当我使用Junit测试verifyToken方法时,我遇到了一个问题:

  • 当异常为null且类型为IOException时,系统调用第二个构造函数IOException构造函数
  • 当异常不为null且实例为IOException时,系统将调用第一个构造函数异常构造函数,而不是IOException构造函数

  • 原因是什么?

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

    空的情况很有趣,这只是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类型的系统不允许运行时重载。< /P>我使用类AuthDigialRealCyExeExchange来避免代码中的多个Test/catch块,所以我不同意第二个选项。在这种情况下,您的代码中会有许多if/else,您可以尝试将其强制转换为switch语句,但这会很困难,因为您无法打开类。不幸的是,您要求的是运行时分支,并且您需要在某个地方有分支语句。@Amine:这种重载并不能为您带来任何好处,只需将其归档即可作为一种学习经验,尝试其他东西。