异常处理的原则:
1目的:异常处理不是为了控制程序的正常流程,它的作用主要是为了捕获在程序运行时发生的异常并进行相应的处理,保证了程序在错误修复后能正常继续运行。
2方式(1)在当前方法中使用try——catch语句捕获并处理异常(包 含自定义的异常)。
(2) 在方法声明处,使用关键字throws将异常向上抛出。
(3)使用catch语句捕获异常后,使用throw关键字重新将异常抛出。
3 并不是在发生任何错误的时候都需要进行异常处理。对于那些可以避免的的异常,则不需要使用。例如下标越界,这类错误只是需要简单的修改就无需进行异常处理。这也是RuntineException类及其子类所描述的异常无需用try catch语句或者throws 抛出。
异常的具体处理方法:
1 使用try..catch 语句。
在try语句块中编写可能发生的异常,然后在catch语句块中捕获执行这些代码时可能发生的异常。 使用格式如下:
try{
可能发生的异常代码
}catch(异常类 异常对象){
异常处理的代码
}
try语句中可能会发生多种异常,到底捕获那一种类型的异常,是由canch语句中的“异常类”参数所决定的。catch相当于方法的声明,包含一个类型和该类型的一个对象。 参数中的异常类类型必须是Throwable类的子类,异常的对象可以在catch语句中被调用,常见的是调用getMessage()的方法显示异常的信息。
public class Test { /* * 使用try catch 处理异常 */ public static void main(String[] args) { try { int age = Integer.parseInt("32L"); System.out.println("蓝杰1"); } catch (NumberFormatException e) { System.out.println("年龄请你输入正确正数!"); System.out.println("错误是:" + e.getMessage()); } System.out.println("打印2"); } }
因为程序执行到Integer.parseInt("32L") 的时候出现了异常,直接跳转到catch语句中捕获,继续执行catch语句中的代码。之后再执try ..catch语句后面的代码。
结果是:
年龄请你输入正确正数!
错误是:For input string: "32L"
打印2
(注意:如果在catch语句中的代码同样不能顺利执行,那么程序就会被终止。例子省略 如在上述例子中添加 int a=10\0)
说明:如果不知道该异常是属于什么类型的异常,可以指定其父类Exceotion类异常
2 如果代码可能存在多种异常,此时可以同时存在多个catch语句块,格式如下:
代码中的每个catch语句会捕获一种异常,如果try中代码存在异常,则会由上而下一次来查找能够捕获该异常的catch语句,并执行该语句后面的代码。
import java.io.IOException; public class Test_2 { /* * 不能确定异常类型使用多个catch语句 */ public static void main(String[] args) { try { int age = Integer.parseInt("32L"); System.out.println("蓝杰1"); } catch (NullPointerException e) { System.out.println("年龄请你输入正确正数!"); System.out.println("错误是:" + e.getMessage()); } catch(Exception e){ System.out.println("-----"+e.getMessage()); } System.out.println("打印2"); } }
结果是:
-----For input string: "32L"
打印2
但是要注意catch语句的顺序,如果catch要捕获的异常是同一种异常或者说是存在继承关系,则要将捕获子类异常的语句放在前边,否则编译的时候会出错。
public class Test_3 { /* * 多个catch语句 注意顺序 */ public static void main(String[] args) { try { int age = Integer.parseInt("32L"); System.out.println("蓝杰1"); } catch (Exception e) { System.out.println("-----" + e.getMessage()); } catch (NumberFormatException e) { System.out.println("年龄请你输入正确正数!"); System.out.println("错误是:" + e.getMessage()); } System.out.println("打印2"); } }
结果是:
Unreachable catch block for NumberFormatException. It is already handled by the catch block for Exception
3 使用throws关键字抛出异常
如果在某方法中出现了异常,不想在当前方法中进行处理,那么可以将该异常抛出,交由调用该方法的上一级进行处理。如果还是不想处理可以继续抛出,但是最终是要进行处理的,否则程序执行不下去。
package cn316; import java.io.File; import java.io.FileWriter; import java.io.IOException; /* * 使用throws关键字 向上抛出异常 */ public class Test_4 { public static void main(String[] args) { try { Write("日本地震了!!!!"); } catch (IOException e) { System.out.println("调用Write方法是出错了。。"); System.out.println("错误是:" + e.getMessage()); } } public static void Write(String name) throws IOException { File file = new File(name); // 创建文件 FileWriter fileOut = new FileWriter(file); fileOut.write("你好,中南大学!"); // 向文件中写入数据 fileOut.close(); // 关闭输出流 fileOut.write("你好,湖南大学"); // 运行时出错 } }
运行结果是:
调用Write方法是出错了。。
错误是:Stream closed
如果是抛出RuntionException类或者是子类的异常可以不使用throws。例如:
package cn316; public class Test_5 { /** * RuntionException类或者子类异常 可以不使用throws */ public static void main(String[] args) { int age = 0; try { age = getAge("21L"); // 调用该方法是抛出异常 } catch (NumberFormatException e) { System.out.println("错误是在:" + e.getMessage()); System.out.println("年龄是:" + "\t" + age); } } public static int getAge(String s) { // 此类异常是NumberFormatException // 可以不使用throws int age = Integer.parseInt(s); return age; } }
运行结果是:
错误是在:For input string: "21L"
年龄是: 0
4 使用throw 关键字
使用throw关键字同样可以抛出异常,与throws不同的是throws用在方法体中,抛出一个异常。throws用于方法的声明中,并且可以抛出多个异常。
使用throws抛出的异常,如果想在上一级中进行处理,同样要是有throws在方法的声明出抛出改异常。同样如果是RuntionException及其子类可以不使用throws。
package cn316; public class MyException extends Exception{//继承Exception类 private String name; //构造函数 public MyException(String name){ this.name=name; } public String getMessage(){ return this.name; } }
package cn316; public class Test_7 { public static void main(String[] args) { try { int myage = getAge("-120"); } catch (NullPointerException e) { System.out.println("-----------------"); } catch (MyException e) { //捕获MyException对象 System.out.println("数据输入的格式错误!!"); System.out.println("原因是:" + e.getMessage()); } } public static int getAge(String name) throws MyException { int age = Integer.parseInt(name); //调用getAge()方法 if (age < 0) { throw new MyException("请重新输入,地球人年龄不能为负数!!"); //抛出MyException异常对象 } return age; } }
运行的结果是:
数据输入的格式错误!!
原因是:请重新输入,地球人年龄不能为负数!!