第74-75集:异常机制、trycatchfinallyreturn执行顺序、捕获异常、声明异常throw、方法重写中异常的处理、手动抛出异常
异常的处理办法一:捕获异常
try
try语句指定了一段代码,该段代码就是一次捕获并处理的范围。在执行过程中,当任意一条语句产生异常时,就会跳过该段中后面的代码。代码中可能会产生并抛出一种或几种类型的异常对象,它后面的catch语句要分别对这些异常做相应的处理。
一个try语句必须带有至少一个catch语句块或一个finally语句块 。【只有try和finally未必可以】
当异常处理的代码执行结束以后,是不会回到try语句去执行尚未执行的代码。
catch
每个try语句块可以伴随一个或多个catch语句,用于处理可能产生的不同类型的异常对象。
-
常用方法:
toString ( ):显示异常的类名和产生异常的原因。
getMessage( ):只显示产生异常的原因,但不显示类名。
printStackTrace( ):用来跟踪异常事件发生时堆栈的内容。【最常用】
这些方法均继承自Throwable类
-
Catch捕获异常时的捕获顺序:
如果异常类之间有继承关系,在顺序安排上需注意。越是顶层的类,越放在下面。再不然就直接把多余的catch省略掉。
finally
有些语句,不管是否发生了异常,都必须要执行,那么就可以把这样的语句放到finally语句块中。
通常在finally中关闭程序块已打开的资源,比如:文件流、释放数据库连接等。
package com.test074;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
public class Test074 {
public static void main(String[] args){
FileReader reader = null;
File a = new File("/Users/wangtao/Desktop/a.txt");
try{
a.createNewFile();
reader = new FileReader("/Users/wangtao/Desktop/a.txt");
char temp = (char)reader.read();
System.out.println("读出的内容"+temp);
} catch(FileNotFoundException e){
System.out.println("文件没有找到");
} catch(IOException e){
e.printStackTrace();
System.out.println("文件读取错误");
} finally {
System.out.println("不管有无异常都将被执行");
try {
reader.close();//这是一个用来关闭对象的方法
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
try、catch、finally、return执行顺序
执行try,catch,给返回值赋值
执行finally
return
package com.test074;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
public class Test074_1 {
public static void main(String[] args){
String str = new Test074_1().openFile();
System.out.println(str);
}
String openFile(){
try{
System.out.println("aaa");
FileInputStream fis = new FileInputStream("/Users/wangtao/Desktop/a.txt");
int a = fis.read();
System.out.println("bbb");
return "step1";
} catch(FileNotFoundException e) {
System.out.println("catch");
e.printStackTrace();
return "step2";//先去finally再回到这里。
} catch(IOException e){
e.printStackTrace();
return "step3";
} finally {
System.out.println("finally!!!");
//return "FFF";//不要在finally中使用return
}
}
}
异常的处理办法二:声明异常:throws子句
当Checked Exception产生时,不一定立刻处理它,可以再把异常Throws出去。
在方法中使用try-chatch-finally这个方法处理异常。在一些情况下,当前方法并不需要处理发生的异常,而是向上传递给调用它的方法处理。
如果一个方法中可能产生某种异常,但是并不能确定如何处理这种异常,则应根据异常规范在方法的首部声明该方法可能抛出的异常。
如果一个方法抛出多个已检查异常,就必须在方法的首部列出所有的异常,之间以逗号隔开。
-
方法重写中声明异常原则:子类声明的异常范围不能超过父类声明的范围。包含如下意思:
父类没有声明异常,子类也不能。
不可抛出原有方法抛出异常类的父类或上层类。
抛出的异常类型的数目不可以比原有的方法抛出的还多(不是指个数)。
package com.test075;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.text.ParseException;
/**
* @author wangtao
* 测试子类重写父类方法
* 1. 子类抛出的异常不能是父类的上层类,其范围也不能超过父类
* 2. 子类抛出的异常种类不能比父类多
* 3. 父类不抛出异常,子类不能抛出。
*
*/
public class Test075_1 {
public static void main(String[] args){
}
class A {
public void method() throws IOException{
}
}
class B extends A {
public void method() throws FileNotFoundException{//子类抛出的异常范围不超过父类范围
}
}
class C extends A {
public void method(){//子类不抛出异常
}
}
class D extends A {
public void method() throws IOException,ParseException{//子类抛出的异常种类比父类多,报错
}
}
class E extends A {
public void method() throws IOException,FileNotFoundException{//子类抛出的异常范围数量虽然多过父类,但是它没有超过父类范围
}
}
class F extends A {
public void method() throws IOException,ArithmeticException{//同上
}
}
}
异常的处理办法三:手动抛出异常
Java异常类对象除在程序执行过程中出现异常时由系统自动生成并抛出,也可根据需要手工创建并抛出。
在捕获一个异常前,必须有一段代码先生成异常对象并把它抛出。这个过程我们可以手工做,也可以由JRE来实现,但是他们调用的都是throw子句。
-
对于一个已经存在的异常类,抛出该类异常对象过程如下:
找到一个合适的异常类。
创建一个该类的对象。
将对象抛出。
package com.test075;
import java.io.File;
import java.io.FileNotFoundException;
public class Test075_2 {
public static void main(String[] args){
File f = new File("/Users/wangtao/Desktop/aaa.txx");
if(!f.exists()){
try {
throw new FileNotFoundException("File can`t be found!");
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
第76集:异常机制、自定义异常、异常总结
自定义异常
在程序中,可能会遇到任何标准异常类都没有充分的描述清楚的问题,这种情况下可以创建自己的异常类【从Exception类或者它的子类派生一个子类即可】
习惯上,定义的类应该包含2个构造器:一个是默认的构造器,另一个是带有详细信息的构造器
package com.test076;
/**
* @author wangtao
* 测试自定义异常
*/
public class Test076 {
public static void main(String[] args){
try {
new TestMyException().test();
} catch (MyException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
class MyException extends Exception {
public MyException(){
}
public MyException(String message){
super(message);
}
}
class TestMyException{
void test() throws MyException {
}
}
使用异常机制建议
要避免使用异常处理代替错误处理,这样会降低程序的清晰性,并且效率低下。
处理异常不可以代替简单测试--- 只在异常情况下使用异常机制
不要进行小粒度的异常处理---应该将整个任务包装在一个Try语句块中
异常往往在高层处理(先了解!后面做项目会说!)
总结
一个图
五个关键字(try,catch,finally,throws,throw)
先逮小的,再逮大的
异常和重写的关系
自定义异常