在使用JdbcTemplate中queryForObject方法的时候抛出一个异常:java
org.springframework.dao.EmptyResultDataAccessException: Incorrect result size: expected 1, actual 0
queryForObject的内部逻辑是这样的:使用queryForObject时,会查询一个结果,当查询中结果多余一个或者没有都会抛出一个异常IncorrectResultSizeDataAccessException
。这个向外抛出的异常为何不须要我使用try-catch处理或者继续向外抛出呢?下面的图片展现这个异常的继承结构。spring
Google以后认识到全部运行时异常均可以不向外抛出。为了更加快速的解决问题,决定对Java异常进行更深刻的学习。学习
首先,Throwable标志这是一个异常。
其次,Throwable有两个子类分别是Error和Exception,Error表示的是JVM发生的异常,如内存溢出,这是应用自身程序自己没法处理的异常;而Exception则表示应用程序自身能够处理的异常。
最后,Exception的子类分为两类,一个是RuntimeException,另外就是其余继承自Exception的异常,如IOException。区分这两类异常主要特性是是否受检。spa
什么是受检异常,什么是非受检异常? 本质上,受检异常指的是会受到Java 编译器检测的异常,也就是说当你的一个方法中有抛出一个受检异常时, 你必须对它进行处理,使用try-catch或者向上抛出进行处理。非受检异常指的是不会受到Java编译器检测的异常, 当你的一个方法中抛出了非受检异常时,你不须要进行处理。 Java意图上使用非受检异常来表示因为软件开发人员致使的错误,如NullPointerException;而使用 受检异常来表示一些用户误操做的错误,如IOException。“The Java Tutorial”告诉咱们一般状况下咱们 应该抛出受检异常,而不要抛出非受检异常。 想想,若是是来自外部的数据有错误,咱们能够抛出异常来讲明用户传入的参数有错误;而若是是开发人员致使的 错误,且咱们开发人员本身都知道本身的代码有异常,那直接改正不久好了,干吗还要向外抛出呢!因此一般是不会 继承非受检异常的。
运行时异常虽然能够不进行处理,可是可能致使线程终止或者应用终止。若是是非主线程,则由Thread.run()抛出异常后,线程终止。若是是主线程(即main方法)抛出异常,则应用终止。线程
有兴趣能够将下面的代码复制到编译器中来检测受检异常和非受检异常。code
public class Main { public void caller() { callee(); } public void callee() throws Exception{ throw new Exception(); } }
上面的代码中在调用callee方法的时候将编译不过。继承
public class Main { public void caller() { callee(); } public void callee(){ throw new RuntimeException(); } }
上面的代码将不会有任何告警。图片