Java的异常处理、自定义异常、try-with-resources

1. Java的异常处理机制

异常是指程序执行的非正常的情况。Java通过面向对象的方式对异常进行处理,Java把异常按照不同的类型进行分类,并提供了良好的接口。Java把所有非正常的情况分为两种:异常(Exception)和错误(Error ),它们都继承Throwable类。Throwable类是所有异常类的父类。

1.1 Error

表示编译时或者系统错误,如虚拟机相关的错误,OutOfMemoryError等,Error是无法处理的

1.2 Exception

Exception能被程序处理,Exception分为两类:RuntimeException(运行时异常)和CheckedException(可检查的异常)

(1)RuntimeException(运行时异常)
RuntimeException类及其子类异常,如NullPointerException(空指针异常)、IndexOutOfBoundsException(下标越界异常)等,这些异常是不可查异常,程序中可以选择捕获处理,也可以不处理。这些异常一般是由程序逻辑错误引起的,程序应该从逻辑角度尽可能避免这类异常的发生。

(2)CheckedException(可检查的异常)
RuntimeException以外的异常,类型上都属于Exception类及其子类。从程序语法角度讲是必须进行处理的异常,如果不处理,程序就不能编译通过。如IOException、SQLException等以及用户自定义的Exception异常,一般情况下不自定义检查异常。

1.3 Error和Exception的区别

Java把所有的非正常的情况分为两种:异常(Exception)和错误(Error ),它们都继承Throwable类。Error错误,一般是指与虚拟机相关的问题,如系统崩溃、虚拟机错误、动态链接失败等,这种错误无法恢复或不可能捕获,将导致应用程序中断。通常应用程序无法处理这些错误,因此应用程序不应该试图使用catch块来捕获Error对象。在定义该方法时,也无须在其throws子句中声明该方法可能抛出Error及其子类。

2. Java的异常处理

Java的异常处理主要依赖于:try、catch、finally、throw、throws五个关键字,关键字作用如下

  • try关键字后紧跟一个花括号括起来的代码块,简称try块,用来放置可能引发异常的代码
  • catch关键字后跟一个异常类型和一个代码块,用于表明该catch块用于处理这种类型异常的代码块
  • finally块用于回收在try块里打开的物理资源,异常机制会保证finally块总被执行
  • throw关键字用于抛出一个实际的异常,可以单独作为语句使用
  • throws 关键字主要在方法签名中使用,用于声明该方法可能抛出的异常

完整的Java异常处理语法结构如下

try{
        //业务处理代码
        ......
}catch(异常种类1 异常对象){
 	//异常处理块1
 	......
}catch(异常种类2 异常对象){
 	//异常处理块1  
        ......
}
finally{
 	//资源回收块
 	......
} 

注意::异常处理语法结果中只有try块是必需的,没有try块,则不能有后面的catch块和finally块;catch块和finally块都是可选的,但catch块和finally块至少出现其一,也可以同时出现;可以有多个catch块,捕获父类异常的catch块必须位于捕获子类异常的后面(先处理小异常,再处理大异常),否则将出现编译错误。多个catch块(多异常捕获)必须位于try块之后,finally块必须位于所有的catch块之后。

2.1 throw和throws的区别

  • throw一般出现在方法内部,用于抛出一个异常,throws一般出现在函数声明的头部
  • throw是具体向外抛出的动作,所以它抛出的是一个异常实体类。若执行了throw一定是抛出了某种异常
  • throws 声明可能抛出的异常,然后交给上层调用它的方法程序处理

2.2 try-catch-finally-return执行顺序

  • 如果不发生异常,不会执行catch块部分;
  • 不管有没有发生异常,finally块都会执行到;
  • 即使try块和catch块中有return时,finally块仍然会执行;
  • finally块如果有return,就不会执行try块或者catch块中的return了;
  • finally是在try块或catch块中return后面的表达式运算完后再执行的。(此时并没有返回运算后的值,而是先把要返回的值保存起来,若finally中无return,则不管finally中的代码怎么样,返回的值都不会改变,仍然是之前保存的值),该情况下函数返回值是在finally执行前确定的)

3. 常见的异常

  • NullPointerException 空指针异常
  • ClassNotFoundException 指定类找不到异常
  • IndexOutOfBoundsException 数组下标越界异常
  • IllegalArgumentException 方法传递参数错误
  • SQLException SQL异常
  • NoSuchMethodException 方法不存在异常

4. 访问异常信息的方法

可以通过访问catch块的异常形参获得。当Java运行时决定调用某个catch块来处理该异常信息时,会将异常对象赋给catch块后的异常参数,程序可通过该参数来获得异常的信息。
异常对象包含了如下几个常用方法:

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

代码测试如下:

public class Exception01 {
   public static void main(String[] args) {
       try {
            System.out.println(5/0);
       }catch(Exception e) {
           e.getMessage();
           e.printStackTrace();
       } 
   }
}

运行输出如下:

java.lang.ArithmeticException: / by zero
 at Exception.Exception01.main(Exception01.java:8)

5. 自定义异常

自定义异常通常是定义一个类继承Exception类或其子类。自定义异常的好处:

  • Java提供的异常体系不可能预见所有的错误;
  • 业务开发中,使用自定义异常,可以让项目代码更加规范,也便于管理;

下面是一个自定义异常的例子:

/**
 *  实现自定义异常
 */
class MyException extends RuntimeException{
 
     public MyException() {
           super();
     }  

     public MyException(String message) {
           super(message);
     }

}

public class MyExceptionTest {

    public void test01(int a) {
	  try {
	   	if(a == 1) {
	    		throw new MyException("传入参数为1异常");
	   	}
	  } catch (MyException e) {
	   	// TODO Auto-generated catch block
	   	e.printStackTrace();
	  }
    }

    public static void main(String[] args) {
  	new MyExceptionTest().test01(1);
    }

}

运行之后结果如下:

Exception.MyException: 传入参数为1异常
 at Exception.MyExceptionTest.test01(MyExceptionTest.java:23)
 at Exception.MyExceptionTest.main(MyExceptionTest.java:33)

6. try-with-resources

try-with-resources,是Java7提供的一个新功能,它用于自动资源管理。它允许在try关键字后跟一对圆括号,圆括号可以声明、初始化一个或多个资源,多个资源之间以;相隔,此处的资源是指那些必须在程序结束后显示关闭的资源(比如数据库连接、网络连接等),try语句在执行结束之后自动关闭这些资源。

  • try-with-resources保证了每个声明了的资源在语句结束的时候会被关闭
  • 为了保证try语句可以正常关闭资源,这些资源实现类必须实现AutoCloseableCloseable接口,实现这两个接口必须实现close()方法。
public static void main(String[] args) throws FileNotFoundException, IOException {
	try(//声明、初始化两个可关闭的资源,try语句会关闭这两个资源
  		BufferedReader br = new BufferedReader(new FileReader("a.txt"));
  		PrintStream ps = new PrintStream(new FileOutputStream("a.txt"))){
  		
  		//使用两个资源
  		System.out.println(br.readLine());
  		ps.println("xingze");
 	}
}

注: 自动关闭资源的try语句相当于包含了隐式的finally块(这个finally块用于关闭资源),因此这个try语句可以既没有catch块,也没有finally块。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值