1.Java 中异常类的体系结构
1.程序运行时出现异常或者错误是一种正常现象,就像人会生病一样。
我们需要重点关注的是程序出错以后怎么办。
2.Java 中异常处理类中的顶级类是java.long.Throwable类。
顶级类--其他的我们见到的异常处理类都是Throwable类的子类。
3.Throwable类产生了两个只要子类,分别是Error【错误】/ Exception【异常】。
2.Error【错误】与 Exception【异常】的区别?
Exception【异常】:程序正常运行中可以预料的意外情况,可能并且应该被捕获,进行相应处理。【感冒】
Exception【异常】被被分为两大类:检查性异常/非检查性异常
Error【错误】:指在正常情况下不大可能出现的情况,绝大部分的Error都会导致程序(比如JVM自身)处于非正常的、不可恢复状态。【癌症晚期】
既然是非正常情况,所以不便于也不需要捕获,常见的比如OutOfMemoryError之类,都是Error的子类。
3.检查性异常与非检查性异常的区别
检查性异常:在源代码里必须显式地进行捕获处理。
FileNotFoundException
try {
FileOutputStream out=new FileOutputStream(new File("F:\\test\\my.txt"));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
非检查性异常:就是所谓的运行时异常,通常是可以编码避免的逻辑错误,具体根据需要来判断是否需要捕获,并不会在编译期强制要求捕获处理。
NullPointerException
package com.wangxing.test1;
public class Student {
public void testStudent(){
System.out.println("Student类的实例方法");
}
}
package com.wangxing.test1;
public class TestMain1 {
public static void main(String[] args) {
Student student=null;
student.testStudent();
}
}
Exception in thread "main" java.lang.NullPointerException
ArrayIndexOutOfBoundsException
package com.wangxing.test1;
public class TestMain1 {
public static void main(String[] args) {
String names[]=new String[3];
names[0]="zhangsan";
names[1]="lisi";
names[2]="wangwu";
names[3]="zhaosi";
}
}
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 3
4.Java异常处理的原理
1.try…catch捕获处理异常
格式:
try{
可能出现异常的java代码
}catch(异常对象){
异常对象---处理异常
}
当程序没有异常的时候,那么程序正常运行不会进入try…catch中;
当程序出现异常的时候,try块就会将出现的具体异常捕获,程序将不会继续向下执行,转而执行catch块,并将try块捕获的异常封装成一个异常对交给catch块,由catch块处理异常,处理完成以后就接着之前出现异常的位置继续向下执行。
package com.wangxing.test2;
public class TestMain2 {
public static void main(String[] args) {
try {
int a = 10;
int b = 0;
int c = a / b;
System.out.println("c==" + c);
} catch (ArithmeticException e) {
e.printStackTrace();
}
}
}
注意:1.将可能出现异常的java代码用try{}块包围。
2.catch后面的异常对象应该是一个具体的异常对象。
我们目前所见到的异常有限,我们可能不能知道这个异常的具体名称,这时我们可以使用Exception或者Throwable对象代替。
package com.wangxing.test2;
public class TestMain2 {
public static void main(String[] args) {
try {
int a = 10;
int b = 0;
int c = a / b;
System.out.println("c==" + c);
} catch (Exception e) {
e.printStackTrace();
}
}
}
package com.wangxing.test2;
public class TestMain2 {
public static void main(String[] args) {
try {
int a = 10;
int b = 0;
int c = a / b;
System.out.println("c==" + c);
} catch (Throwable e) {
e.printStackTrace();
}
}
}
3.一个try{}块后面可以有多个catch块,多个catch块要按照异常类型由小到大排列。
package com.wangxing.test2;
public class TestMain2 {
public static void main(String[] args) {
try {
int a = 10;
int b = 0;
int c = a / b;
System.out.println("c==" + c);
}catch (ArithmeticException e) {
System.out.println("假装出里异常");
e.printStackTrace();
}catch (Exception e) {
System.out.println("假装出里异常");
e.printStackTrace();
}catch (Throwable e) {
System.out.println("假装出里异常");
e.printStackTrace();
}
}
}
4. finally{}块出现在最后一个catch块后面,无论程序是否发生异常都会执行。
package com.wangxing.test2;
public class TestMain2 {
public static void main(String[] args) {
try {
int a = 10;
int b = 0;
int c = a / b;
System.out.println("c==" + c);
}catch (ArithmeticException e1) {
System.out.println("假装出里异常");
e1.printStackTrace();
}catch (Exception e2) {
System.out.println("假装出里异常");
e2.printStackTrace();
}catch (Throwable e3) {
System.out.println("假装出里异常");
e3.printStackTrace();
}finally{
System.out.println("无论程序是否发生异常都会执行");
}
}
}
由于异常Exception本身是程序正常运行中可以预料的意外情况,我们通过修改程序可以避免这个异常的发生,所以我们在try{}catch(Exception e){}的catch块中不进行具体异常的处理,而是通过异常对象的printStackTrace()方法将异常类型和异常原因以及出现异常的位置找到,然后修改程序来避免这个异常的发生。
2.不断向上抛出,交由jvm来处理
throws--声明方法抛出异常
访问限制修饰符 返回值类型 方法名称([参数])throws 异常类型{}
访问限制修饰符 返回值类型 方法名称([参数])throws 异常类型1,异常类型2...{}
throws--声明方法抛出异常,结果是在那里调用这个方法你就要处理方法上的异常
1.try…catch捕获处理异常
package com.wangxing.test3;
public class Person {
//throws--声明方法抛出异常
//访问限制修饰符 返回值类型 方法名称([参数])throws 异常类型{}
public void testPerson()throws Exception{
int num=10/0;
System.out.println("num=="+num);
}
}
package com.wangxing.test3;
public class TestMain3 {
public static void main(String[] args) {
Person p1=new Person();
try{
p1.testPerson();
}catch(Exception e){
e.printStackTrace();
}
}
}
2.向上抛出,交由jvm来处理
package com.wangxing.test3;
public class TestMain3 {
public static void main(String[] args)throws Exception {
Person p2=new Person();
p2.testPerson();
}
}
Exception in thread "main" java.lang.ArithmeticException: / by zero
at com.wangxing.test3.Person.testPerson(Person.java:7)
at com.wangxing.test3.TestMain3.main(TestMain3.java:15)
5.throw 关键字的用法
throw关键字表示手动产生一个异常。
目的:为了提醒用户怎么操作。
throw new 异常类名称([提示语言]);
通过一个简单的自定义异常来使用throw关键字
自定义异常:java开发库中没有提供,我们自己创建的异常。
很多收java发库中提供异常类型是满足我们的开发使用的,很少自定义异常。
怎么做一个自定义异常的简单的方法:
1.创建一个新类,继承一下Exception/Throwable。
2.重新构建一下子类的构造方法,通过super([参数])调用父类的构造方法。
package com.wangxing.test4;
/*
怎么做一个自定义异常的简单的方法:
1.创建一个新类,继承一下Exception/Throwable
2.重新构建一下子类的构造方法,通过super([参数])调用父类的构造方法。
*/
public class MyException extends Exception{
public MyException(String msg){
super(msg);
}
}
package com.wangxing.test4;
/**
* 创建数组的java类
* @author Administrator
*
*/
public class MyArray {
//数组大小
private int size;
//通过构造方法设置数组大小
public MyArray(int size)throws MyException{
if(size<=0){
//手动产生一个异常,提示提醒用户不用使用负数
throw new MyException("数组大小不能是负数!");
}else{
this.size=size;
}
}
//创建一个字符串类型的数组
public String[] createArray(){
String stringarray[]=new String[this.size];
return stringarray;
}
}
package com.wangxing.test4;
public class TestMain4 {
public static void main(String args[])throws Exception{
MyArray myarray1=new MyArray(-1);
String name[]=myarray1.createArray();
}
}
Exception in thread "main" com.wangxing.test4.MyException: 数组大小不能是负数!
at com.wangxing.test4.MyArray.<init>(MyArray.java:14)
at com.wangxing.test4.TestMain4.main(TestMain4.java:4)