Java异常处理
一、异常的分类
所有的异常类是从java.lang.Exception类继承的子类
Exception类是Throwable类的之类。除了Exception类外,Throwable还有一个子类Error
Java程序通常不捕获错误。错误一般发生在严重故障时,它们在Java程序处理的范畴之外
Error用来指示运行时环境发生的错误
例如:JVM内存溢出。一般地,程序不会从错误中恢复
异常类有两个主要的子类:IOException类和RuntimeException类
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-A7RmZurj-1623114166824)(C:\Users\lzl52\AppData\Roaming\Typora\typora-user-images\image-20210607231334244.png)]
二、编译异常的处理
-
try…catch
package com.qjzx._04_exception; import java.rmi.NotBoundException; public class StudentTest { public static void main(String[] args) { Student st = new Student("王五",-1); try { st.viewIntel(); //catch如果同时捕获多个类型,这多个异常类型不能有继承关系 } catch (IllegalAccessException | NotBoundException | RuntimeException e) { e.printStackTrace(); } System.out.println(456); } }
-
throws 向上传播/抛出
异常可以向上传播
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JzZ9N5UA-1623114166834)(C:\Users\lzl52\AppData\Roaming\Typora\typora-user-images\image-20210607231451170.png)]
运行时异常如果没有处理,自动向上传播
编译异常需要在方法签名处通过throws关键字声明传播的异常类型
public class StudentTest {
public static void main(String[] args) throws IllegalAccessException, NotBoundException {
Student st = new Student("王五",-1);
st.viewIntel();
System.out.println(456);
}
}
三、finally关键字
-
语法
finally用在try…catch语句块中,表示最终会执行的代码
finally语句之前,如果有执行退出虚拟机,也是不会执行finally语句块
无论是否产生异常,finally一定会执行
public class StudentTest { public static void main(String[] args) { Student st = new Student("赵六",14); try { st.viewIntel(); //上一句代码可能会抛出异常,也可能不会 //如果抛出了,则这句代码肯定不会执行到 //有些情况下,我们要求,即使抛出了异常,这句代码也必须执行到 // System.out.println("123"); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (NotBoundException e) { e.printStackTrace(); } finally { System.out.println("123"); } System.out.println("456"); } }
设计到资源的释放,链接的关闭这些,和异常捕获一起来用的时候,要放入到finally语句块中
-
异常处理的语句执行顺序
return和finally
package com.qjzx._05_finally; import java.rmi.NotBoundException; public class StudentTest { public static void main(String[] args) { System.out.println(test()); } /** * return 和 finally谁先执行 * 执行的return语句 是在 finally 的 上方 还是 下面 * @return */ public static int test() { Student st = new Student("赵六",14); int i = 20; try { st.viewIntel(); //上一句代码可能会抛出异常,也可能不会 //如果抛出了,则这句代码肯定不会执行到 //有些情况下,我们要求,即使抛出了异常,这句代码也必须执行到 // System.out.println("123"); return i; } catch (IllegalAccessException e) { e.printStackTrace(); } catch (NotBoundException e) { e.printStackTrace(); } finally { System.out.println("这个是执行了的"+(++i)); } return i; } }
return会终止方法的继续执行
throw也会终止方法的执行
方法有结果:
- 有值返回
- 有异常抛出
四、面试题
-
finally和final的区别
没有可比性
-
final 可选修饰符
类:类为最终类,不能被继承
变量:常量,值不能更改
方法:最终方法,不能被重写
-
finally:
用在try…catch语句块中,表示一定会执行的代码块
-
-
throw和throws的区别
- throw关键字用在方法体中,用来抛出异常对象
- throws用在方法签名中,表示这个方法抛出的异常类型
-
return和finally的执行顺序
return会终止方法的继续执行
throw也会终止方法的执行
//这种写法是没问题的
try {
}finally {
}
五、自定义异常
如果java中提供的异常类型不符合我们的使用场景,我们也可以自定义异常类型
自定义异常
-
运行时异常
继承RuntimeException
-
编译异常
继承Exception
/**
* 自定义一个运行时异常:年龄不合法异常
* @author Administrator
*
*/
public class AgeNotAccessException extends RuntimeException{
public AgeNotAccessException(String message) {
super(message);
}
}
/**
* 编译异常:未成年异常
* @author Administrator
*
*/
public class NotYetOfAgeException extends Exception{
public NotYetOfAgeException(String message) {
super(message);
}
}
public class Student {
private String name;
private int age;
public Student() {}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
/**
* 上网 一个方法同时只能抛出一个异常对象
*/
public void viewIntel() throws NotYetOfAgeException{
if(age <= 0) {
throw new AgeNotAccessException("年龄不合法!");
}else if(this.age >= 18) {
System.out.println("上网真好耍!");
}else {
//异常!
//创建异常对象并“抛出”
throw new NotYetOfAgeException("你还未成年呢!");
}
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
public class StudentTest {
public static void main(String[] args) {
//运行时异常都会通过合理的代码逻辑进行规避
//运行时异常不需要捕获和处理的
int age = -1;
if(age <= 0) {
age = 18;
}
Student st = new Student("王八",age);
try {
st.viewIntel();
} catch (NotYetOfAgeException e) {
e.printStackTrace();
}
System.out.println(123);
}
}
static void main(String[] args) {
//运行时异常都会通过合理的代码逻辑进行规避
//运行时异常不需要捕获和处理的
int age = -1;
if(age <= 0) {
age = 18;
}
Student st = new Student("王八",age);
try {
st.viewIntel();
} catch (NotYetOfAgeException e) {
e.printStackTrace();
}
System.out.println(123);
}
}