JAVA-throw new IOException报错unhandled exception:java.lang.Exception 2021年6月7日

今天搞懂了两个问题

  1. check Exception 和 unchecked Exception 的区别
  2. try-catch和throw,throws的区别

今天遇到一个bug,需要这样处理:Feign调用如果失败了,则不更新数据库

处理feign调用获取返回值的方法是这么写的


package com.common.Util;

import com.alibaba.fastjson.JSON;
import com.common.base.FeignResponse;
import com.common.enums.ErrorCodeEnum;
import com.service.feign.IFunction;
import com.exception.BusinessException;
import lombok.extern.slf4j.Slf4j;

import java.util.Objects;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.function.Supplier;

@Slf4j
public class FeignUtils {

public static <T, U, C, R> R getData(ErrorCodeEnum errorCode, T t, U u, C c , IFunction<T, U, C, FeignResponse<R>> function) {
FeignResponse<R> response;

try {
response = function.apply(t, u, c);
} catch (Exception e) {
log.error("Feign调用失败, 调用参数:[{}][{}]", JSON.toJSONString(t) ,JSON.toJSONString(u), e);
throw new BusinessException(ErrorCodeEnum.FEIGN_CALL_FAILED.getCode(),"Feign调用失败");
}
return handelResponse(errorCode, response);
}

public static <T, U, R> R getData(ErrorCodeEnum errorCode, T t, U u, BiFunction<T, U, FeignResponse<R>> function) {
FeignResponse<R> response;

try {
response = function.apply(t, u);
} catch (Exception e) {
log.error("Feign调用失败, 调用参数:[{}][{}]", JSON.toJSONString(t) ,JSON.toJSONString(u), e);
throw new BusinessException(ErrorCodeEnum.FEIGN_CALL_FAILED.getCode(),"Feign调用失败");
}
return handelResponse(errorCode, response);
}

public static <T, R> R getData(ErrorCodeEnum errorCode, T param, Function<T, FeignResponse<R>> function) {
FeignResponse<R> response;
try {
response = function.apply(param);
} catch (Exception e) {
log.error("Feign调用失败, 调用参数:[{}]", JSON.toJSONString(param) , e);
throw new BusinessException(errorCode.getCode(),"Feign调用失败", e);
}
return handelResponse(errorCode, response);
}


public static <T, R> R getData(ErrorCodeEnum errorCode, Supplier<FeignResponse<R>> function) {
FeignResponse<R> response;
try {
response = function.get();
} catch (Exception e) {
log.error("Feign调用失败", e);
throw new BusinessException(errorCode.getCode(),"Feign调用失败",e);
}
return handelResponse(errorCode, response);
}

private static <R> R handelResponse(ErrorCodeEnum errorCode, FeignResponse<R> response) {

if (Objects.isNull(response) || !Objects.equals("0", response.getCode())) {
throw new BusinessException(errorCode.getCode(),JSON.toJSONString(response.getMsg()));
}
return response.getData();
}
}
 

在try中捕获异常,catch中throw异常,调用getData的方法还会继续执行吗?

断点调试直接抛出异常,程序结束

try-catch和throw,throws的区别:

1.throw

throw 就是抛出一个异常,并获取这个异常的引用,这个异常会被抛到外部的环境,由外部环境进行处理

try catch是直接处理,处理完成之后程序继续往下执行,throw则是将异常抛给它的上一级处理,程序便不往下执行了。

2.throws

throws并不是抛出一个实际的Exception而是一个异常声明,它声明这个方法可能会抛出一个异常,注意是可能,所以在没有异常的情况下也是可以用throws的,而throws本身的作用也是用来提高程序的健壮性,反过来,如果这个方法的的确确的有一个异常,那么编译器会强制让你加上throws这个异常声明。

3.try catch

在try块里经常放上可能会抛出异常的程序段

catch恰好就是处理try里抛出来的异常,其中catch的参数列表接收的是一个异常的引用,是throw抛出来的异常的引用,这样我们就可以得到这个异常的对象

总结:在程序中有异常的代码被try catch后,后边的代码能够继续执行,如果是throws 出来的,则运行到异常代码处就会停止执行,抛出异常

写了一段测试代码验证

public static void main(String[] args){
        try {
            a();
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("s");
    }
    public static void a() {
        try {
            int a = 1;
            int b = a/0;
        } catch (Exception e) {
            throw new Exception("Feign调用失败");
        }
    }

上面代码报错:unhandled exception:java.lang.Exception

发现 throw new RuntimeException 不会报错

而  throw new Exception 和  throw new IOException 会报错

如果将测试代码改为如下,则不报错

public static void main(String[] args){
        try {
            a();
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("s");
    }
    public static void a() throws IOException{
        try {
            int a = 1;
            int b = a/0;
        } catch (Exception e) {
            throw new IOException("Feign调用失败");
        }
    }

或将测试代码改为如下,也不报错

public static void main(String[] args){
        try {
            a();
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("s");
    }
    public static void a(){
        try {
            int a = 1;
            int b = a/0;
            throw new IOException("Feign调用失败");
        } catch (Exception e) {
        }
    }

因为Exception是check异常,也就是必须在代码层面直接捕获处理的

checked: 一般是指程序不能直接控制的外界情况,是指在编译的时候就需要检查的一类exception,用户程序中必须采用try catch机制处理或者通过throws交由调用者来处理。这类异常,主要指除了Error以及RuntimeException及其子类之外的异常。

unchecked:是指那些不需要在编译的时候就要处理的一类异常。在java体系里,所有的Error以及RuntimeException及其子类都是unchecked异常。再形象直白的理解为不需要try catch 等机制处理的异常,可以认为是unchecked的异常。

                 +-----------+
                 | Throwable |
                 +-----------+
                  /         
                 /           
          +-------+          +-----------+
          | Error |          | Exception |
          +-------+          +-----------+
           /  |             / |         
          \________/       \______/         
                                        +------------------+
          unchecked        checked      | RuntimeException |
                                        +------------------+
                                         /   |    |      
                                        \_________________/
                        
                                            unchecked
原文地址:https://www.cnblogs.com/jingbostar/p/14860598.html