一、Java中的异常处理
java中的异常处理类中的最顶级类是java.lang.Throwable类
Throwable产生了两个直接子类,分别是Error【错误】/Exception【异常】
二、Error【错误】与 Exception【异常】的区别?
Exception【异常】:程序正常运行中可以预料的意外情况,可能并且应该被捕获,进行相应处理。
Error【错误】:指在正常情况下不大可能出现的情况,绝大部分的Error都会导致程序(比如JVM自身)处于非正常的、不可恢复状态。既然是非正常情况,所以不便于也不需要捕获,常见的比如OutOfMemoryError之类,都是Error的子类。
三、Exception【异常】分类
1.检查性异常:在源代码里必须显式地进行捕获处理
2.非检查性异常:就是所谓的运行时异常,通常是可以编码避免的逻辑错误,具体根据需要来判断是否需要捕获,并不会在编译期强制要求捕获处理。
处理非检查性异常[运行时异常]的步骤
1.查找出现异常的位置【看控制台输出的错误信息】
2.确定具体的异常类型
3.编码避免
如何查找出现异常的位置和确定具体的异常类型?如何才能输出异常提示信息?
通过try{}catch(具体异常对象){}将异常提示信息输出。具体异常对象.printStackTrace();---打印堆栈异常
四、Java异常处理的原理
1.try…catch捕获处理异常---将异常提示信息输出
格式:
try{
可能出现异常的java代码
}catch(异常对象){
异常对象---处理异常
}
当程序没有异常的时候,那么程序正常运行不会进入try…catch中;
当程序出现异常的时候,try块就会将出现的具体异常捕获,程序将不会继续向下执行,转而执行catch块,并将try块捕获的异常封装成一个异常对象交给catch块,由catch块处理异常,处理完成以后就接着继续向下执行。
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();
}
}
}
注意:i.将可能出现异常的java代码用try{}块包围。
ii.catch后面的异常对象应该是一个具体的异常对象。
我们目前所见到的异常有限,我们可能不能知道这个异常的具体名称,这时我们可以使用Exception或者Throwable对象代替。
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();
}
}
}
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();
}
}
}
iii.一个try{}块后面可以有多个catch块,多个catch块要按照异常类型由小到大排列
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();
}
}
}
iv. finally{}块出现在最后一个catch块后面,无论程序是否发生异常都会执行。
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--声明方法抛出异常,结果是在那里调用这个方法你就要处理方法上的异常
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();
}
}
}
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)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)
*/
五、throw关键字的用法
throw关键字表示手动产生一个异常【故意制造异常】。
目的:为了提醒用户怎么操作。
格式:throw new 异常类名称([提示语言]);
自定义异常:java开发库中没有提供,我们自己创建的异常。很多时候java发库中提供异常类型是满足我们的开发使用的,很少自定义异常。
怎么做一个自定义异常的简单的方法:
1.创建一个新类,继承一下Exception/Throwable
2.重新构建一下子类的构造方法,通过super([参数])调用父类的构造方法。
//创建一个新类,并继承Exception类,重构子类构造函数,用super调用父类的构造方法
public class MyException extends Exception{
public MyException(String msg){
super(msg);
}
}
/*
创建数组的java类
*/
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;
}
}
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)
*/