Java异常处理
1.使用try、catch处理异常。
2.认识异常继承架构。
3.认识throw、throws的使用时机
4.运用finally关闭资源
5.使用自动关闭资源语法
6.AutoCloseable接口
一、try、catch处理异常
Scanner console=newScanner(System.in);
int number =console.nextInt();
如果输入不是整形的话会出现InputMismatchException。此时便可以用try catch来捕捉异常并做些处理。
二、异常处理架构
完整的见JDK API
如果使用继承时,父类的某个方法声明throws某些异常,子类重新定义该方法时
可以:
1.不声明throws任何异常
2.throws父类该方法中的某些异常
3.throws父类方法中声明异常的子类
但是不可以
1.throws父类方法中未声明的某些异常‘
2.throws父类方法中声明异常的父类
关键字:
try:用来指定一块预防所有异常的程序
catch:紧跟在try后面,用来捕获异常
throw:用来明确的抛出一个异常
throws:用来标明一个成员函数可能抛出的各种异常
finally:确保一段代码无论发生什么异常都会被执行的一段代码
四、使用finally关闭资源
在下面代码(1)中如果在close()之前出现异常那么该方法就不执行了此时资源就没有关闭所以使用(2)中的finally来使得该块中的代码一定被执行。注意如果程序中先
return了finally的会先执行后返回值。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
(1) public static String readFile(String name)throws FileNotFoundException{ StringBuilder text=new StringBuilder(); Scanner scanner=new Scanner(new FileInputStream(name)); while(scanner.hasNext()){ text.append('\n'); } scanner.close(); return text.toString(); } (2) public static String readFile(String name)throws FileNotFoundException{ StringBuilder text=new StringBuilder(); Scanner scanner=null; try{ scanner=new Scanner(new FileInputStream(name)); while(scanner.hasNext()){ text.append('\n'); } }finally{ if(scanner!=null){ scanner.close(); } } return text.toString(); } }
五、使用自动关闭资源
语法:try(自动关闭资源的对象){某块代码执行完之后执行关闭资源}//JDK之后新增的语法
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
try(Scanner scanner=new Scanner(new FileInputStream(name))){ while(scanner.hasNext()){ text.append('\n'); } }
addSuppressed()方法,java.lang.throwable ,JDK7之后新增的方法,与之对应的是getSuppressed()返回的是throwable[]代表先前加入的异常对象。
主要流程是(1)先定义throwable对象tr1,(2)在可能发生异常的尝试捕捉所有的错误Throwable 对象tr2,(3)在catch快中tr1=tr2抛出tr2;(4)若捕捉到错误则要进行资源关闭
关闭资源可能发生错误得捕捉错误tr3,(5)把tr3在tr2中记录在tr2中记录如果没有异常就直接关闭资源
详细代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
public static String readFile(String name)throws FileNotFoundException{ StringBuilder text=new StringBuilder(); Scanner scanner=new Scanner(new FileInputStream(name)); Throwable localThrowable2=null;//定义throwable对象 try{ while(scanner.hasNext()){ text.append('\n'); }//捕捉异常块 }catch(Throwable localThrowable1 ){//尝试捕捉所有的错误 localThrowable2=localThrowable1; throw localThrowable1; }finally{ if(scanner!=null){//判断是否有参考到实例 if(localThrowable2!=null){//如果前面有异常 try{ scanner.close();//尝试关闭异常 }catch(Throwable x2){//万一关闭异常出现错误 localThrowable2.addSuppressed(x2);//在原异常对象中记录 } } else{ scanner.close();//没有发生任何异常直接关闭 } } } return text.toString(); } }
六、AutoCloseable接口
JDK7.0新增的接口
代码如下
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
package Learn; public interface AutoCloseable { void close() throws Exception; }
操作AutoCloseable接口关闭资源,try中越后面的资源越早被关掉。为啥呢?见下面第二段代码
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
package Learn; public class AutoCloseableDemo { public static void main(String[] args) { try(ResourceSome some=new ResourceSome();ResourceOther other=new ResourceOther()){ some.doSome(); other.doOther(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } } class ResourceSome implements AutoCloseable{ void doSome(){ System.out.println("some"); } @Override public void close() throws Exception { // TODO Auto-generated method stub System.out.println("someclosed"); } } class ResourceOther implements AutoCloseable{ public void doOther() { // TODO Auto-generated method stub System.out.println("other"); } @Override public void close() throws Exception { // TODO Auto-generated method stub System.out.println("otherclosed"); } } 结果如下 some other otherclosed someclosed
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
try{ ResourceSome some=new ResourceSome(); Throwable Throwable3=null;//定义throwable对象 try{ ResourceOther other=new ResourceOther(); Throwable Throwable4=null;//定义throwable对象 try{ some.doSome(); other.doOther(); }catch(Throwable localThrowable1){ Throwable4=localThrowable1; throw localThrowable1; }finally{ if(localThrowable4!=null){//如果前面有异常 try{ other.close();//尝试关闭异常 }catch(Throwable x2){//万一关闭异常出现错误 localThrowable4.addSuppressed(x2);//在原异常对象中记录 } } else{ other.close();//没有发生任何异常直接关闭 } } }catch(Throwable localThrowable2){ localThrowable3=localThrowable2; throw localThrowable2; }finally{ if(localThrowable3!=null){//如果前面有异常 try{ some.close();//尝试关闭异常 }catch(Throwable x2){//万一关闭异常出现错误 localThrowable3.addSuppressed(x2);//在原异常对象中记录 } } else{ some.close();//没有发生任何异常直接关闭 } } }catch(Exception ex){ ex.printStackTrace(); }
摘抄:
1、error和exception有什么区别
error表示系统级的错误,是java运行环境内部错误或者硬件问题,不能指望程序来处理这样的问题,除了退出运行外别无选择,它是Java虚拟机抛出的。
exception 表示程序需要捕捉、需要处理的异常,是由与程序设计的不完善而出现的问题,程序必须处理的问题
2、运行时异常和一般异常有何不同
Java提供了两类主要的异常:runtimeException和checkedException
一般异常(checkedException):主要是指IO异常、SQL异常等。对于这种异常,JVM要求我们必须对其进行cathc处理,所以,面对这种异常,不管我们是否愿
意,都是要写一大堆的catch块去处理可能出现的异常。
运行时异常(runtimeException):我们一般不处理,当出现这类异常的时候程序会由虚拟机接管。比如,我们从来没有去处理过NullPointerException,而且
这个异常还是最常见的异常之一。
出现运行时异常的时候,程序会将异常一直向上抛,一直抛到遇到处理代码,如果没有catch块进行处理,到了最上层,如果是多线程就有Thread.run()抛出,如
果不是多线程那么就由main.run()抛出。抛出之后,如果是线程,那么该线程也就终止了,如果是主程序,那么该程序也就终止了。
其实运行时异常的也是继承自Exception,也可以用catch块对其处理,只是我们一般不处理罢了,也就是说,如果不对运行时异常进行catch处理,那么结果不
是线程退出就是主程序终止。
如果不想终止,那么我们就必须捕获所有可能出现的运行时异常。如果程序中出现了异常数据,但是它不影响下面的程序执行,那么我们就该在catch块里面将异
常数据舍弃,然后记录日志。如果,它影响到了下面的程序运行,那么还是程序退出比较好些。
3、Java中异常处理机制的原理
Java通过面向对象的方式对异常进行处理,Java把异常按照不同的类型进行分类,并提供了良好的接口。在Java中,每个异常都是一个对象,它都是Throwable
或其子类的实例。当一个方法出现异常后就会抛出一个异常对象,该对象中包含有异常信息,调用这个对象的方法可以捕获到这个异常并对异常进行处理。Java的
异常处理是通过5个关键词来实现的:try catch throw throws finally。
一般情况下是用try来执行一段程序,如果出现异常,系统会抛出(throws),我们可以通过它的类型来捕捉它,或最后由缺省处理器来处理它(finally)。
try:用来指定一块预防所有异常的程序
catch:紧跟在try后面,用来捕获异常
throw:用来明确的抛出一个异常
throws:用来标明一个成员函数可能抛出的各种异常
finally:确保一段代码无论发生什么异常都会被执行的一段代码。
4、你平时在项目中是怎样对异常进行处理的。
(1)尽量避免出现runtimeException 。例如对于可能出现空指针的代码,带使用对象之前一定要判断一下该对象是否为空,必要的时候对runtimeException
也进行try catch处理。
(2)进行try catch处理的时候要在catch代码块中对异常信息进行记录,通过调用异常类的相关方法获取到异常的相关信息,返回到web端,不仅要给用户良好
的用户体验,也要能帮助程序员良好的定位异常出现的位置及原因。例如,以前做的一个项目,程序遇到异常页面会显示一个图片告诉用户哪些操作导致程序出现
了什么异常,同时图片上有一个按钮用来点击展示异常的详细信息给程序员看的。
5、final、finally、finalize的区别
(1)、final用于声明变量、方法和类的,分别表示变量值不可变,方法不可覆盖,类不可以继承
(2)、finally是异常处理中的一个关键字,表示finally{}里面的代码一定要执行
(3)、finalize是Object类的一个方法,在垃圾回收的时候会调用被回收对象的此方法。