1、Java语言的异常处理机制
1.1异常
异常是指在程序运行中由代码产生的一种错误。Java语言提供的异常处理机制是通过面向对象的方法来处理异常的。所以在Java语言中所有异常都是以类的形式存在的,除了内置的异常类之外,Java语言也允许用户自己定义异常类
1.2抛出异常
如果在程序运行过程中出现异常,系统自动生成一个异常对象,该异常对象被提交给j运行系统的过程,称为抛出异常
1.3捕获异常
当j运行系统收到异常对象时,会寻找能处理该异常对象的catch块,如果找到合适的catch块并把该异常对象交给catch块处理,那这个过程称为捕获(catch)异常;如果java运行时环境找不到捕获异常的catch块,则运行时环境终止,java程序也将退出
2、异常处理类
2.1异常类结构图
2.2 Throwable派生了Error和Exception
2.2.1Throwable():
Throwable 类是 Java 语言中所有错误或异常的超类。只有当对象是此类(或其子类之一)的实例时,才能通过 Java 虚拟机或者 Java throw 语句抛出。类似地,只有此类或其子类之一才可以是 catch 子句中的参数类型。
2.2.2Error:
一般是指java虚拟机相关的问题,如系统崩溃、虚拟机出错误、动态链接失败等,这种错误无法恢复或不可能捕获,将导致应用程序中断,通常应用程序无法处理这些错误,因此应用程序不应该捕获Error对象,也无须在其throws子句中声明该方法抛出任何Error或其子类。
2.2.3.Exception:
Exception 类及其子类是 Throwable 的一种形式,它指出了合理的应用程序想要捕获的条件
(1). RuntimeException 是那些可能在 Java 虚拟机正常运行期间抛出的异常的超类
(2).IOException:此类为异常的通用类,它是由失败的或中断的 I/O 操作生成的。
异常对象包含的常用方法:
getMessage();返回该异常的详细描述字符
printStackTrace():将该异常的跟踪栈信息输出到标准错误输出。
printStackTrace(PrintStream s):将该异常的跟踪栈信息输出到指定的输出流
getStackTrace():返回该异常的跟踪栈信息。
3、异常的处理
在Java语言中,异常处理是通过try、catch、finally、throw、throws五个关键字来实现的
3.1使用try-catch-finally语句捕获和处理异常
3.1.1语法结构:
try
{
要检查的语句序列
...
}
catch(SubException e)
{
异常发生时的处理语句序列1
...
}
catch(SubException2 e)
{
异常发生时的处理语句序列2
...
}
...
finally
{
一定会运行的语句序列
//资源回收块
...
}
1 public class TestException
2 {
3
4 public static void main(String[] args)
5 {
6
7 try{
8 FileInputStream fis=new FileInputStream("a.txt");
9 }
10 catch(IOException ioe)
11 {
12 System.out.println(ioe.getMessage());
13 ioe.printStackTrace();
14 }
3.1.2 注意
以上的异常处理语法结构中
1:只有try块石必须的,也就是说如果没有try块,则不可能有后面的catch块和finally块;
2:catch块和finally块都是可选的,但catch块和finally块至少出现其中之一,也可以同时出现;
3:可以有多个catch块,捕获父类异常的catch块必须位于捕获子类异常的后面;
4:不能只有try块,既没有catch块,也没有finally块;
5:多个catch块必须位于try块之后,finally块必须位于所有catch块之后;
6:上面的格式中try块和catch块后的{···}都是不可省略的!
3.1.3多异常处理
多异常机制是通过在一个try块后面定义若干个catch块来实现的,每个catch块用来接收和处理一种特定的异常对象
4、抛出异常
4.1抛出异常的方式
4.1.1方式一:
在方法体内使用throw语句抛出异常对象,其语法格式为:
throw 由异常类所产生的对象;
其中“由异常类所产生的对象”一个从Throwable派生的异常类对象
(用new运算符来产生对象)。
public class Exception1 {
public static void main(String [] args) {
int a=0,b=0;
try {
if (b==0){
throw new ArithmeticException(); //抛出异常
}else {
System.out.println(a+"/"+b+"="+a/b);
}
}catch (ArithmeticException e){
System.out.println("异常:"+e+"被抛出了!");
e.printStackTrace();
}
}
}
输出
异常:java.lang.ArithmeticException被抛出了!
java.lang.ArithmeticException
at swu.syq.lib5.lib10.Exception1.main(Exception1.java:118)
Process finished with exit code 0
4.1.2方式二:
在方法头部添加throws子句表示方法将抛出异常,其语法格式为:
[修饰符]返回值的类型 方法名([参数列表]) throws 异常类列表
其中,throws是关键字,“异常类列表”是方法中要抛出的异常类,当异常类多于一个的时候,要用逗号‘,’隔开。
//使用throws抛出异常
public static void test() throws FileNotFoundException,NullPointerException{
FileReader fr=new FileReader("");
}
5、自定义异常类
定义异常类,需要基础Exception基类,如果希望定义RuntimeException基类,就应该继承该基类。
定义异常类时通常需要提供两种构造器:
1,无参的构造器
2,带字符串的构造器,这个字符串作为该异常对象的详细说明,(也就是异常对象的getMessage方法返回值),调用super将字符串参数传给异常对象的message属性,message属性就是异常对象的详细描述信息。
public class Exception1 {
public static void main(String [] args){
try {
TException.test3();
} catch (PXDException e) {
System.out.println(e.getMessage());
}
}
}
class TException{
//使用throws抛出异常
public static void test() throws FileNotFoundException,NullPointerException{
FileReader fr=new FileReader("");
}
//使用throw抛出一个自己创建的异常对象
public static void test1() throws IllegalAccessException {
//
if (2>1){
throw new IllegalAccessException();
}
}
public static void test3() throws PXDException{
//
StackTraceElement[] stackTrace=Thread.currentThread().getStackTrace();
StackTraceElement e=stackTrace[2];
String detail=e.getFileName()+"->"+e.getMethodName()+"->"+e.getLineNumber();
//自己定义输出
throw new PXDException("自己的异常类"+detail);
}
}
//自定义异常:能够自己定义输出内容 更快地找到出现问题的位置
class PXDException extends Exception{
//第1步、提供一个无参构造方法
public PXDException(){}
//第2步、提供一个有参构造方法 参数是一个字符串
public PXDException(String desc){
super(desc);
}
}
6、小结
对异常的处理:
*在方法内使用try-catch语句来处理方法本身所产生的异常
*如果不想在当前方法中使用try-catch语句来处理异常,可在方法声明的头部使用throws语句或在方法内部使用throw语句将它送往上一层调用机构去处理
*对于非运行时异常,Java要求必须进行捕获并处理,而对运行时异常则不必,可以交给Java运行时系统来处理