java异常主要包括异常体系和异常处理
异常体系
java异常体系是Throwable类,Error类和Exception类都是是它的子类
Error类是错误的意思,程序一旦出现错误则程序终止,是不可修复的,必须修改源代码才可以;Exception类是异常的意思,程序一旦出现异常,有可能会被修复,主要看出现异常类型,Exception类又分为可检查性异常和运行时异常。
Error类有一个常见子类,就是 OutOfMemoryException内存溢出错误
例如:
//Error错误
//OutOfMemoryError内存溢出错误
int []i = new int[1000*1000*1000];
System.out.println(i.length);
Exceptionl类有一个RuntimeException的子类
RuntimeException类:运行时异常,这些异常出现时可能被程序员避免,可以在程序编译时被忽略。
以下是RuntimeException类的一些常见子类:
-
ClasscastException:类型转换异常
例如://ClassCastException类型转换异常 //向上转型 Animal dog = new Dog(); //向下转型 Cat cat = (Cat)dog;
-
NullPointerException:空指针异常
例如:public class CommonException { String str; public static void main(String[] args) { //NullPointerException空指针异常 //例1-对象指向了控制的属性str // new CommonException().str.charAt(0); //例2-CommonExceptionm没有指向具体对象而引用了CommonException的getStr方法 CommonException c = null; c.getStr(); } }
-
IndexOutOfBoundsException:索引越界异常
例如://IndexOutOfBoundsException索引越界异常 String str1 = "123"; System.out.println(str1.charAt(10));
-
ArithmeticException:算数异常
例如://ArithmeticException算数越界异常 int x = 10; int y = 0; System.out.println(x/y);
-
Exception类除了运行时异常剩下的基本是可检查异常(CheckedException)
以下是一些常见的可检查异常:
- FileNotFoundException文件没找到异常
- IOException输入输出异常
- SqlException操作数据库异常
异常处理(主要有两种处理方式)
-
try-catch-finally(自己处理)
try块:负责监控可能出现异常的代码,如果有异常,try块后面的catch块就会被检查catch:负责捕获可能出现的异常,并进行处理,catch里面有相应的异常参数,如果与出现的异常一致则处 理异常
finally块:负责清理各种资源,不管是否出现异常都会执行
注意事项:1.异常捕获必须要有try块,try块后面不能既没catch块也没finally块,至少要有一个
2.try块后面可以跟多个catch块,当try块出现异常,异常会依次抛给后面的catch块,如此直到异常被捕获或通过多有的catch块,最后抛给java虚拟机(不处理),这种方式叫多重捕获
3.finally/catch块并非强制要求有的,但必须要有其中一个跟在try块后面
4.finally/catch不能独立于try块存在
例如:public static void test() { System.out.println("开始运行"); int[] i = {}; try { System.out.println("以下代码可能出现异常"); // try { i[0] = 1; // } // catch(IndexOutOfBoundsException c) { // System.out.println("我是嵌套异常处理"); // } System.out.println("我是以下代码,我没出异常"); } catch(IndexOutOfBoundsException c) { System.out.println("我是嵌套异常处理"); } finally { System.out.println("我是必须执行的代码"); } System.out.println("异常处理结束,程序继续运行"); }
程序输出为:
开始运行 以下代码可能出现异常 我是嵌套异常处理 我是必须执行的代码 异常处理结束,程序继续运行
被注释掉的是一个try-cach的嵌套使用,可以让出现异常代码后面的代码执行。
-
throws throw(自己不处理)
1.出现异常时抛给调用者处理,调用者可以选择catch或者继续往上抛,都过所有上层都没有处理,最终会抛给java虚拟机,处理方式为中断程序运行
2.抛出异常(throws+抛出异常类)写在方法签名的最后面,可以抛出多个异常,用逗号隔开
例如:public class ThrowsAndThrow { public static void main(String[] args) /*throws FileNotFoundException*/{ try { readFile("c:/www"); } catch(FileNotFoundException a) { System.out.println("解决异常"); } } public static char[] readFile(String fileName) throws FileNotFoundException{ return readFile1(fileName); } public static char[] readFile1(String fileName) throws FileNotFoundException{ return readFile2(fileName); } public static char[] readFile2(String fileName) throws FileNotFoundException{ //throw new FileNotFoundException(); throw new RuntimeException(); } }
-
try - catch - finally与throws throw的关系
它们不是上下层的关系,而是相互依靠的关系,try - catch - finally可以捕获异常,但是它不能决定在哪一层去捕获异常,throws throw可以把异常抛到上层,但它不能捕获异常,要靠try - catch - finally去捕获异常
自定义异常
-
自定义异常必须是Throwable的子类
-
如果要自定义一个检查性异常类,则需要继承Exeption类
-
如果要自定义一个运行时异常类,则需要继承RuntimeException类