JAVA异常处理
1、什么是异常?
异常就是不正常,不正常就是异常。
就是在我们设计程序中不可避免一些意外情况的发生,比如:两个数除,分母为零。操作数据库的时候,数据库没有打开。还有一些客观因数造成的:读取文件的时候,文件不存在等。
如果我们在设计程序的时候不考虑这些问题,那么我们的程序就显得非常的不健壮。所以我们设计程序的时候就应该考虑到这些意外情况的放生,并作出相应的预案。
2、异常处理
JAVA语言的设计者已经为我们考虑到了N种异常情况的处理,但是还有一些异常时需要我们自己去处理的。当异常发生的时候,我们可以选择(try-catch-finally)直接处理掉异常,也可以(throw-throws)不直接处理,而是抛出该异常。
3、异常处理工作原理
抛出异常,捕获异常,处理异常。
当异常情况发生的时候,产生一个异常事件,创建一个异常对象并由导致该错误的方法抛出。该方法可以选择自己处理异常或者抛出异常。两种情况下,该异常被捕获并处理。被JAVA抛出的异常可能与违反语言规范有关或超出Java执行环境限制有关。
4、异常处理的五大关键字
JAVA异常处理通过五大关键字控制:try,catch,throw,throws,finally。
你需要监控可能放生异常的语句放在try块中,try块中放生异常将会抛出,接着使用catch捕获该异常,并采用合适的方法处理该异常。系统产生的异常被java运行时系统自动抛出。如果你需要手动抛出一个异常,使用throw关键字,任何被抛出方法的异常都必须通过throws子句定义。任何在方法返回前绝对被执行的代码被放置在finally块中。
5、异常处理的通用形式
try{
这里放有可能发生异常的代码
throw:方法体内主动抛出异常
}catch(Exception e){
一旦发生了异常在这里进行处理
}finally{
不论是否发生异常都要执行的代码
比如:关闭数据库的连接
}
注:这里的try,catch,finally可以结合switch理解。
一个try可以搭配多个catch。但是,同一时刻,只可能有一个catch被执行,我们的推荐做法是把Exception的catch放到最后。
6、异常处理的类层次
JAVA通过错误类(error)和异常类(exception)来处理错误和异常,而它们都是Throwable类的子类,分别用来处理两组异常。它们的层次结构如下:
常见的错误类(Error)与异常类(Exception)的子类:
A:RuntimeException类的子类
(1)算数异常:ArithmeticException
(2)空指针异常:NullPointException
(3)类型强制转化异常:ClassCastException
(4)数组下标越界异常:ArrayIndexOutOfBoundsException
(5)数组负下标异常:NegativeArraySizeException
B:检查异常的子类:
(1)类或接口不能找到异常:ClassNotFoundException
(2)一般的与外部有关的异常:SQL,网络连接中断等
C:Error的子类:
(1)因为内存溢出或没有可用的内存提供给垃圾回收器时,Java 虚拟机无法分配一个对象:OutOfMemoryError
(2)当应用程序递归太深而发生堆栈溢出:StackOverFlowError
7、程序对错误与异常处理的三种形式
(1)程序不能处理的错误,Error类为错误类。
(2)程序应避免而不捕获的异常,RuntimeException类为运行时异常类。如数组下标越界等,无需使用try-catch-finally语句,这类异常应通过程序调试尽量避免而不是去捕获它。
(3)程序必须捕获的异常,有些异常在编写程序时是无法预料的,入文件没找到异常,网络通信失败异常等。因此,为了保证程序的健壮性,java要求必须对可能出现这些异常的代码使用try-catch-finally语句,否则编译无法通过。
8、错误与异常的区别?
A:相同点
(1)都是Throwable的子类
(2)都是程序不正常的表现
B:不同点
(1)致命性的错误:这类不正常是发生在JVM层次的,是属于非常严重的错误,同时也是不可控制的,一旦发生这类错误程序本身是不能处理的。
(2)非致命性的异常:这类不正常是发生在应用程序层次的,有的可以控制有的不能控制,如果程序员对异常做了相应的处理,一旦发生异常程序本身是可以处理异常的。
9、RuntimeException异常与检查异常的区别?
主要区别在于:抛出运行时异常,上级可以处理也可以不管。如果抛出检查异常,上级必须对该异常进行处理。
10、自定义异常
(1)定义一个类继承Exception类或者RuntimeException类
(2)定义该类的构造方法
(3)抛出自定义异常
(4)处理自定义异常
注:throw语句用在方法体内,表示抛出异常,由方法体内的语句处理。不能单独使用,要么和try- catch一起使用,要么和throws一起使用。throws语句用在方法声明后面,表示这个方法可能会抛出异常,表示的是一种倾向、可能,但不一定实际发生。由调用这个方法的上一级方法中的语句来处理 。后面可以跟多个异常,中间用逗号分割。
package exception;
/**
* 自定义异常测试类
* @author Administrator
*
*/
public class Test {
public static void main(String[] args) {
Demo demo = new Demo();
//不用try-catch处理就会自动交给main方法
demo.sayRuntimeException();
//不try-catch就手动抛给main方法
try {
demo.sayException();
} catch (MyException e) {
e.printStackTrace();
}//finally{}可以省略
}
}
//定义一个类抛出自定义异常
class Demo{
//如果继承Exception类的异常不使用try-catch处理就必须使用throws向上抛
public void sayException() throws MyException {
throw new MyException();
}
//如果继承RuntimeException类可以不处理,不手动向上抛,由系统自动向上抛
public void sayRuntimeException(){
throw new MyException1();
}
}
//自定义一个异常类继承Exception类
class MyException extends Exception{
public MyException() {
System.out.println("自定义异常,继承Exception");
}
}
//自定义一个异常类继承RuntimeException类
class MyException1 extends RuntimeException{
public MyException1() {
System.out.println("自定义异常,继承RuntimeException");
}
}