栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Java异常那些事

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Java异常那些事

1. 受检异常和非受检异常
  • 非受检异常:继承RuntimeException的异常都是非受检异常,非受检异常不需要在函数上明确声明throws exception;

  • 那么为啥异常要分受检和非受检呢。如果需要明确函数抛出的异常,那么就需要明确一下,并且编译器会自动监测受检异常是否处理,否则会编译报错。非受检异常,这个表示是运行期错误,是不应该发生的,发生了就应该出错才对。

  • 那么我们写程序的时候,到底是写受检异常好呢还是非受检异常好。其实不管是定义受检和还是非受检,都要在适当的时候捕获异常,不能因为非受检异常编译器不检查,就不处理异常了,特别是需要资源释放等场景时都要主动去捕获异常。

2. 捕获异常重新生成异常,cause不要忘了
  1. 先看一下不输出异常cause,那么获取的异常堆栈是什么样的?
    首先看一下,如果捕获异常后直接生成新的异常,不带cause,下游输出异常栈的结果是什么?
try {
	try {
		double r = 1/0;
	} catch (Exception e) {
		throw new NewException(e.getMessage());
	}
} catch(Exception e) {
	e.printStackTrace();
}

输出结果异常堆栈信息是,这样的话,只知道异常是由throw new NewException这个地方抛出的,但是什么原因导致这个异常抛出,就不知道了。

org.example.NewException: / by zero
	at org.example.AppTest.testException(AppTest.java:99)
  1. 如果加上异常cause,那么异常堆栈是什么样的?
    把上面的抛出异常的语句改一下,改成加上异常原因的方式,throw new NewException(e.getMessage(), e);
try {
	try {
		double r = 1/0;
	} catch (Exception e) {
		throw new NewException(e.getMessage(), e);
	}
} catch(Exception e) {
	e.printStackTrace();
}

输出的异常堆栈如下:
因为加上了异常cause,所以很清楚知道最源头的异常是如何发生的。

org.example.NewException: / by zero
	at org.example.AppTest.testException(AppTest.java:99)
Caused by: java.lang.ArithmeticException: / by zero
	at org.example.AppTest.testException(AppTest.java:97)```
  1. 备注,NewExeption的定义如下:
class NewException extends Exception{
    public NewException(String msg) {
        super(msg);
    }
    public NewException(String msg, Throwable e) {
        super(msg, e);
    }
}
3. finnally 对return的影响
  1. 如果finnally中也有return语句,那么输出结果是什么?
    如下所示,那么test的最终返回结果是try中的ret++,还是ret+3?正确答案是:首先计算try中的return语句,ret++,此时ret=1,然后把返回结果1记录下来,这个时候再去执行finally中的return语句,这个时候直接返回ret + 3,即结果是4,那么 直接返回。所以,最终的输出结果是4。
public int test() {
        int ret = 0;
        try {
            return ret++;
        } catch (Exception e) {
            throw new NewException(e.getMessage(), e);
        } finally {
            return ret+3;
        }
    }
  1. 如果finnally中没有return语句,但是也对try中的return变量,做了操作,会影响try中的return结果吗?
    最终test输出结果是1,finally中的ret+2不会影响return结果。为啥呢?因为try中return中的语句执行完成之后,会把计算结果值拷贝下来,然后再去计算finally中的语句,finally不会对return语句的结果造成影响。
public int test() throws NewException {
        int ret = 0;
        try {
            return ret + 1;
        } catch (Exception e) {
            throw new NewException(e.getMessage(), e);
        } finally {
            ret = ret + 2;
            System.out.println("result:" + ret);
        }
    }
  1. 综上所述,不要在finally中return结果,以免影响try中的return结果。其次,finally中对try中return的变量做操作,不会影响
4. try中释放资源

try语句中后面带有一个(),()理解可以创建资源,比如文件、网络端口,等try语句执行完成之后,会自动调用资源的close方法,释放资源。

try(Resource res1 = new Resource();Resource res2 = new Resource())//可指定多个资源,用;隔开{
		xx
     }                                                                       

如果不使用该方法,之前的方法,需要在finally中主动释放

try {
	Resource res1 = new Resource();
 } catch (Exception ex) {
    ex.printStackTrace();
} finally {
    if (res1 != null) {
       rest1.close();
    }
}
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/287382.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号