JavaSE_43th_异常的捕获和处理(try-catch-finally)

一、异常的捕获和处理
1)实现一个可以抛出异常的方法:

package com.hpe.exception;

public class TestEx2 {
	
	public static void main(String[] args) {
		TestEx2 te = new TestEx2();
		te.m(0);
	}
	
	void m(int i) throws ArithmeticException {
		if(i == 0) {
			throw new ArithmeticException("除数为0");
		}
	}
}
运行结果:

Exception in thread "main" java.lang.ArithmeticException: 除数为0
 at com.hpe.exception.TestEx2.m(TestEx2.java:12)
 at com.hpe.exception.TestEx2.main(TestEx2.java:7)

总结:
这个异常属于RuntimeException,即使不捕获,程序也是可以运行起来的,只是运行时会出异常,而且程序会停止运行。

2)我们也可以选择捕获这个异常:

package com.hpe.exception;

public class TestEx2 {

	public static void main(String[] args) {

		try {
			new TestEx2().m(0);
		} catch (ArithmeticException e) {
			System.out.println(e.getMessage());
		}
	}

	void m(int i) throws ArithmeticException {
		if (i == 0) {
			throw new ArithmeticException("出错啦,除数为0");
		}
	}
}

运行结果:

出错啦,除数为0
总结:
a、使用我们自己写的catch语句来捕获异常可以使提示变得友好,而且程序可以继续往下执行。
b、异常类都有构造方法,可以传入字符串以表示该异常对象的一些信息,通过getMassage()方法可以返回这些字符串信息。


3)对于一些非RuntimeException异常,如果不捕获或抛出,编译器会提示错误,程序是无法运行的。

package com.hpe.exception;

import java.io.FileInputStream;

public class TestEx3 {

	public static void main(String[] args) {
		
		FileInputStream in =  new FileInputStream("myfile.txt");
	}
}

无法通过编译。

4)下面开始介绍必须要捕获或抛出的非RuntimeException。
可以使用多个catch语句捕获不同的异常

package com.hpe.exception;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

public class TestEx3 {

	public static void main(String[] args) {
		
		FileInputStream in = null;  
		try {
			in = new FileInputStream("myfile.txt");
			int b = in.read();
			while(b != -1) {
				System.out.println((char)b);
				b = in.read();
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
			
		} catch (IOException e) {
			System.out.println(e.getMessage());
			
		} finally {
			try {
				in.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}

5)f1()方法处理不了的异常可以抛给调用f1()方法的地方去处理。

package com.hpe.exception;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

public class TestEx4 {

	public static void main(String[] args) {
		
		new TestEx4().f2();
	}
	
	void f1() throws FileNotFoundException, IOException {
		FileInputStream in = null;  
		in = new FileInputStream("myfile.txt");
		int b = in.read();
		while(b != -1) {
			System.out.println((char)b);
				b = in.read();
		}
	}
	
	void f2() {
		try {			
			f1();
		} catch (FileNotFoundException e) {
			System.out.println(e.getMessage());
		} catch (IOException e) {
			e.printStackTrace();
		}
	} 
}

6)异常可以一直往方法外抛。

package com.hpe.exception;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

public class TestEx4 {

	public static void main(String[] args) {
		
		try {
			new TestEx4().f2();
		} catch (FileNotFoundException e) {
			System.out.println("捕获到FileNotFoundException!");
		} catch (IOException e) {
			System.out.println(e.getMessage());
		}
	}
	
	void f1() throws FileNotFoundException, IOException {
		FileInputStream in = null;  
		in = new FileInputStream("myfile.txt");
		int b = in.read();
		while(b != -1) {
			System.out.println((char)b);
				b = in.read();
		}
	}
	
	void f2() throws IOException {
		f1();
	} 
}

运行结果:

捕获到FileNotFoundException!

总结:
a、如果所抛出的多个异常中有一个异常类是其他异常类的父类,可以只抛这个父类异常,即就算不显式地写出要抛子类异常,子类异常也会被抛出,因为子类异常都属于父类异常的一种。在try-catch的时候,再去catch子类异常,这样也是可以的,但不推荐这种写法,因为如果简化了所抛出的异常种类,甚至直接throws Exception,在对所调用的方法进行捕获的时候,根本不知道会抛出哪种异常,不便于写分门别类的多分支catch语句,所以建议将可以抛出的异常全部写全,而不是只写一个父类异常了事。
b、main方法也可以将异常往外抛,抛给Java虚拟机。

5)总结:
a、try代码段包含可能产生异常的代码。
b、try代码段后跟有一个或多个catch代码段。
c、每个catch代码段声明其能处理的一种特定类型的异常,并提供处理的方法。
d、每当异常发生时,程序会终止当前的流程,根据所获取异常的类型去执行相应的catch代码段。
e、如果没有异常产生,所有的catch代码段都被略过不执行。
f、finally段的代码无论是否发生异常都会被执行。


7)try语句
a、try{...}语句指定了一段代码,该段代码是可能会发生异常的代码。
b、在执行过程中,该段代码可能会产生并抛出一种或几种类型的异常对象,它后面的catch语句要分别对这些异常做相应的处理。
c、如果没有异常产生,所有的catch代码段都被略过

8)catch语句
a、在catch语句块中是对异常进行处理的代码,每个try语句块可以伴随一个或多个catch语句,用于处理可能产生的不同类型的异常对象。
b、在catch语句中声明的异常对象封装了异常事件发生的信息,在catch语句块中可以使用异常对象的一些方法获取异常的相关信息。
3)如:

getMessage()  //用来得到有关异常事件的信息。
printStackTrace()//用来跟踪异常事件发生时执行堆栈的内容

8)finally语句
a、finally语句为异常处理提供一个统一的出口,使得在控制流程转到程序的其他部分以前,能够对程序得状态做统一的管理。
b、无论try所指定的程序块中是否抛出异常,finally指定的代码都要被执行。
c、通常在finally语句中可以进行资源的清除工作。


9)需要注意的一些细节:

package com.hpe.exception;

public class TestEx5 {

	public static void main(String[] args) {
		int[] arr = {1, 2, 3};
		
		try {			
			System.out.println(arr[5]);
		} catch (Exception e) {
			System.out.println("有异常发生了");
		} catch (ArrayIndexOutOfBoundsException e) {
			System.out.println("数组下标越界了");
		}
	}
}
编译器会报错,在一个try-catch语句中,父类异常的捕获语句不可以写在子类异常捕获语句的上面。
把握一个原则:在捕获异常的时候,要先逮小的,再逮大的。






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值