当前位置:首页 > Java技术 > Java异常处理机制

Java异常处理机制

2022年08月05日 09:43:23Java技术2

来源:流浪舟 https://index.maliaoblog.cn

与C++、python,Ruby一样,Java也有一个异常处理机制,当程序出现异常时,系统会自动生成一个Exception对象通知程序去处理。之所以这样设计目的在于使程序有更好的容错性和可读性,实现业务代码和错误处理代码的分离。比如:

try{
	//业务代码
}catch(ExceptionClass e){
	//处理代码
}catch(Excepton i){//括号内为形参
    //是不是有点像if-else语句
}

抛出:生成一个异常对象后,异常送给运行环境处理,这里并不是什么严格定义,理解就行。那另一个专业词捕获意思是把异常交给catch异常处理块,就是catch异常,如果找不到合适的catch块会结束程序。每个catch块会处理专门的异常,就像园括号里的。多个catch块针对不同的异常,但每次只有一个catch块被执行。同时需要注意的是,catch块是不能访问try块的局部变量,只在try块中有效。

异常类的继承和分类

分类:
Java异常处理机制 _ JavaClub全栈架构师技术笔记
所以从上面的图来看,非正常情况分为两种,ExceptionError。Error一般是指虚拟机相关的问题,如:虚拟机错误,系统故障等无法用程序修复的,结果就是程序中断。其实还可以把异常分为两大体系:Checked检查异常,Runtime运行时异常,所有RuntimeException类及其子类实例成为运行时异常,其他异常为可检查异常(认为可修复处理的,必须显式处理否则无法通过编译)。

程序总是把Exception异常放到最后,如果放到前面,程序将直接进入该catch块,try块异常语句后面其他块不会有机会被执行。(所以异常对象是Exception及其子类的实例) 原则上应该先处理小异常,再处理大异常

Java7提供多捕获异常

从Java7开始catch块可以捕获多个异常,注意以下几点即可:

  1. 多种异常用|隔开 2.异常变量不能被重新赋值,即它们都是隐式的final修饰
catch(FileNotFoundExcepton e|ArithmeticException i){...}

访问异常信息,异常跟踪栈

异常对象一般有以下几个方法:

  • getMessage():返回异常的详细描述
  • printStackTrace():将异常跟踪栈信息到标准错误输出
  • printStackTrace(PrintStream s):将异常跟踪栈信息输出到指定流
  • getStackTrace():返回该异常的跟踪栈信息(注意是返回)

一系列方法被调用,形成了方法栈,发生异常时,异常向方法调用者传播,然后再传给其调用者...,跟踪栈记录程序异常发生点,执行停止位置,并标明类、方法、所在行。跟踪栈总是最内部的被调用方法上传,直到最外部操作起点,通常为main方法或Thread类的run方法。

finally关键字

在异常处理中,这里的finally不是必要的,那为啥要增添一个不必要的关键字呢?前面一篇提到过GC垃圾回收机制只会回收堆内存中的资源,不会回收其他资源(比如像网络连接、文件、数据库连接等)。为了保证一定能回收这些资源,机制提供了finally关键字去处理。也就是说,finally块的优先级是比较高的,即使trycatch强制方法返回,除非要强制退出JVM,如System.exit(1)

异常处理嵌套

嵌套是指异常处理的代码的嵌套,可以在trycatchfinally块中。

finally{
	if(file != null){
		file.close();
	}
}

Java7增强了try语句,允许后面紧跟圆括号,括号内可声明,初始化多个需关闭的资源,也就是说,不用finally块也能最后回收这些资源,这里是指不用显式的块,其实还是隐式的用它。前提是,这些资源类必须实现AutoCloseable或Closeable接口,即需要重写close方法。Java7几乎把资源类都改写了,改写后都实现了两个或一个的接口。

Closeable是AutoCloseable的子接口,可以被自动关闭的类要么实现Closeable接口,要么实现AutoCloseable接口,但都需要实现close方法。Closeable接口的close方法只能抛出IOException异常,所以实现时只能抛出其及子类;而AutoCloseable的close方法能抛出所有异常类。

try(BufferedReader br = new BufferedReader("Test.java");
	PrintStream ps = new PrintStream(new FileOutputStream("a.txt"));){
	System.out.println(br.readLine());
	ps.println("ok!");
	}

throws声明

当程序不知道如何处理这种异常时,会将异常抛出,交给上级处理。如果main方法不知道处理,同样throws抛出异常给JVM处理。JVM会打印异常跟踪栈信息,中止程序运行。用法就是只能在方法签名中使用,但是可以抛出多个异常类。

throws IndexOutBoundsException,IOException...//抛出异常类

throws抛出异常时有限制:子类方法抛出的异常要是父类抛出异常类型或其子类,且不能比父类抛出的异常还多。

相对来说,抛出Runtime异常是比较省事的。

throw

当程序出现错误,系统会自动抛出异常,Java程序也会抛出异常。自行抛出异常由throw语句实现,注意没有sthrow语句可以单独使用,像普通程序语句一样,重要的是:它抛出的不是异常类,而是实例对象throw自行抛出的异常同样会中止当前程序执行,然后跳到相应的catch块处理异常。同时为了更好的处理异常,让用户有一个完美的体验,throwcatch可以结合使用,程序对异常部分处理,然后抛给调用者处理。

public void test() throws MyException{
	try{
		...
	}catch(Exception e){
		throw new MyException("抛出给方法调用者");
	}
}

如果throw语句抛出的是checked异常,throw语句可以放在try块中捕获,也可以放在带throws声明的抛出方法中,把异常交给该方法的调用者处理;如果抛出的是Runtime异常,则无须放在try块,也无需放在带throws声明的方法中。但是真的要处理的话,程序可以try...catch捕获该异常,也可以也可以不用理会。

这里需要提一下throw语句的一个变化:在Java7以前,编译器根据throw语句抛出的异常类型从而判定该方法需要声明throws抛出的异常类型,而Java7开始,增强了语句,编译器会根据实际判断throw语句处的异常类型,从而该方法可以声明抛出实际的异常类型。

public void test() throws FileNotFoundException{
	try{
		new FileOutputStream("a.txt");
	}catch(Exception e){
		e.printStackTrace();
		throw e;
	}
}

自定义异常

抛出异常时,选择合适的异常很有必要,所以需要自定义异常。自定义异常则需要继承Exception类,或继承RuntimeException异常。定义异常通常要两个构造器,一个无参,一个有参(字符串参数,描述异常详细信息,即getMessage方法返回值)

public class MyException extends Exception{
	public MyException(){} //需要的话可以换成RuntimeException
	public MyException(String msg){
		super(msg);//调用父类构造器
	}//msg会传给异常对象的message属性
}

异常链

在实际的开发中,原始的异常信息往往是不被外界用户所知晓的,但是异常发生时需要通知用户情况,因此在处理异常时会进行异常的链式处理

public test() throws MyException{
	try{
		//业务代码
	}catch(Exception e){
	//原始异常记录下来...
		throw new MyException("系统出现未知异常");//用户提示 
	}
}

这种捕获一个异常然后抛出一个异常,并把原始异常信息保存下来,被称为“异常链”,是一种典型的链式处理模式:职责链模式

JDK1.4开始,Throwable子类重载了一个构造器,该构造器可接收一个cause对象作为参数,cause表示原始异常,那这样就能把原始异常传给新异常,从而进行链式处理。

try{
//
}catch(SQLException e){
	//记录异常,再抛出异常对象
	throw new SQLException(e);
}catch(Exception e){
	throw new SQLException(e);
}

构造器很简单,如下:

public MyException(Throwable t){
	super(t);
}//已继承Exception类

异常处理规则

  1. 不要过度使用异常
  2. 不要使用过大的try
  3. 避免使用catchall 语句
  4. 不要忽略捕获的异常

异常处理的初衷是将业务代码和异常处理代码分离,所以别另作他用!此外,需要注意的是,异常处理的效率比正常的流程控制的差,所以异常处理使用过多也不是好事。catch All语句虽然可以处理所以异常,但需要分情况处理时得不偿失,或者需要得到特定异常时。


公众号: 菜鸡干Java
流浪舟 https://index.maliaoblog.cn

作者:江南骚年
来源链接:https://www.cnblogs.com/coderma/p/13715013.html

版权声明:
1、JavaClub(https://www.javaclub.cn)以学习交流为目的,由作者投稿、网友推荐和小编整理收藏优秀的IT技术及相关内容,包括但不限于文字、图片、音频、视频、软件、程序等,其均来自互联网,本站不享有版权,版权归原作者所有。

2、本站提供的内容仅用于个人学习、研究或欣赏,以及其他非商业性或非盈利性用途,但同时应遵守著作权法及其他相关法律的规定,不得侵犯相关权利人及本网站的合法权利。
3、本网站内容原作者如不愿意在本网站刊登内容,请及时通知本站(javaclubcn@163.com),我们将第一时间核实后及时予以删除。


本文链接:https://www.javaclub.cn/java/18053.html

标签: Exception
分享给朋友:

“Java异常处理机制” 的相关文章

报org.mybatis.spring.MyBatisSystemException: nested exception is `***.ReflectionException解决方法!

错误描述: 1.数据库中表(se_seat)设计 字段 数据类型 seSeatId varchar seSeatName...

java 异常处理

java 异常处理

一:什么是异常  异常是程序中的一些错误,但并不是所有的错误都是异常,并且错误有时候是可以避免的。  比如说,你的代码少了一个分号,那么运行出来结果是提示是错误 java.lang.Error;如果你用System.out.println(11/0),那么你是因为你用0做了...

Mybatis报错org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.builder.Bu

Mybatis报错org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.builder.Bu

使用spring+Mybatis報錯org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.builder.BuilderException: Er...

java异常处理中的返回值

java异常处理中的返回值

项目github地址:bitcarmanlee easy-algorithm-interview-and-practice 欢迎大家star,留言,一起学习进步 1.try-catch中的返回值 java代码中,有各种各样的try-catch...

java异常详细讲解

一起学习 1. 异常机制 1.1 异常机制是指当程序出现错误后,程序如何处理。具体来说,异常机制提供了程序退出的安全通道。当出现错误后,程序执行的流程发生改变,程序的控制权转移到异常处理器。 1.2 传统的处理异常的办法是,函数返...

Java异常处理和设计

Java异常处理和设计

#cnblogs_post_body h2 { background: rgba(64, 108, 164, 1) !important; margin: 15px 0 !important; padding: 5px 0 5px 20px; border-radius: 4px !i...

Mybatis异常处理之MySQL Connector Java] will not be managed by Spring

Mybatis异常处理之MySQL Connector Java] will not be managed by Spring

很长时间没写后台代码有点生疏了,这不今天又出点小插曲,写个文章记录下。 由于要上传点数据到后台,顺手整了个mybatis+springmvc。在保存数据时出现了异常。 Creating a new SqlSession SqlSession [org.apache...

java mybatis org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.

org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.exceptions.PersistenceException: ### Error qu...

Java中的异常处理:何时抛出异常,何时捕获异常,何时处理异常?

Java中的异常处理:何时抛出异常,何时捕获异常,何时处理异常?

1.具体明确(异常类型) 2.提早抛出(1抛更具体的异常类型,2 更好的定位) 3.延迟捕获 (在能处理的时候捕获,而不是把它‘吃掉’ Java中的异常处理:何时抛出异常,何时捕获异常? 2017-06-07   1 异常分类...

SSM

org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.exceptions.TooManyResultsException: Expected one result (or...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。