异常.
在程序执行中发生的不正常情况
语法错误和逻辑错误都不是异常
异常(广义)分为
- Error:java虚拟机无法解决的严重错误,一般不编写针对性代码进行处理
- JVM系统内部错误
- 资源耗尽
- 。。。
- Exception:其他因编程错误或偶然的外在因素导致的一致性问题,可以使用针对性代码处理
- 空指针
- 数组索引越界
- 。。。
Exception异常分为
- 编译时异常(checked):运行javac.exe时,出现的异常
- 运行时异常(unchecked):运行java.exe时,出现的异常
异常体系结构.
java.lang.Throwable
java.lang.Error
一般不编写针对性代码进行处理java.lang.Exception
可以使用针对性代码处理- 编译时异常(常见举例)
IOException
FileNOTFoundException
ClassNotFoundException
- 运行时异常
RuntimeException
(常见举例)NullPointerException
ArrayIndexOutOfBoundsException
ClassCastException
NumberFormatException
InputMismatchException
ArithmaticException
- 编译时异常(常见举例)
异常的处理 抓抛模型.
过程一: “抛”:程序在正常执行的过程中,一旦出现异常,就会在异常代码处生成一个对应异常类的对象,并将此对象抛出
一旦抛出对象以后,其后的代码就不在执行
- 关于异常对象的产生: ① 系统自动生成的异常对象 ②手动的生成一个异常对象,并抛出(throw)
过程二:“抓”:可以理解为异常的处理方法:①try-catch-finally ②throws
异常处理方式.
1.try-catch-finally.
一般处理编译时异常,将一个编译时可能会出现的异常,延迟到运行时出现
try{
//可能出现异常的代码 异常代码后续的代码,就不在执行了。
}catch(异常类型1 e){
//处理异常
//1. e.getMessage();
//2. e.printStackTrace();
}catch(异常类型2 变量名2){
//处理异常
}
......
catch(异常类型n 变量名n){
//处理异常
}finally{//可选
//一定会执行的代码 不管是否有异常 不管try或catch里是否有return
//资源的释放 : JVM 无法回收物理连接占用的资源,必须手动释放
}
2.throws + 异常类型.
public void method() throws 异常类型1,异常类型2,...,异常类型n {}
同样处理编译时异常
一旦方法执行时,出现异常,仍会在异常代码处生成一个异常类的对象,此对象满足throws后异常类型时,就会被抛出。异常代码后续的代码,就不在执行了。
main()
方法抛出的throws
异常是由JVM处理
try-catch-finally
是真正处理了异常(捕获,处理)
throws
的方式只是将异常抛给了方法的调用者。并没有将异常处理掉。(继续抛出)
开发中如何使用try-catch-finally
还是 throws
?.
- 如果父类中被重写的方法上没有使用
throws
抛出异常,则如果子类存在异常,子类重写的方法也不能使用throws
,只能使用try-catch-finally
处理 - 先后调用另外几个方法,这几个方法是递进关系(多层调用),底层方法遇到异常采用
throws
,最上层使用try-catch-finally
处理- 原因,如果底层使用
try-catch-finally
处理,会导致每个底层方法都会执行(延迟到运行时) - 如果使用的是
throws
处理,只要遇 会抛出异常,后面的代码都不用执行,即后面的调用方法也不会执行
- 原因,如果底层使用
以上两种异常处理的异常都是 系统自动生成的异常.
手动抛出异常(throw
).
if(生成异常的条件){
throw new RuntimeException("自定义抛出异常信息");//运行时异常
}
if(生成异常的条件){
throw new Exception("自定义抛出异常信息");//包含编译,运行异常, 编译时就生成,一般使用throws抛出让调用方法处理
}
用户自定义异常类.
public class MyException extends RuntimeException{
static final long serialVersionUID = -7034897190745766939L;//序列版本号
public MyException() {
}
public MyException(String msg) {
super(msg);
}
}
使用
public class Student {
private int id;
//登记id
public void regist(int id){
if(id < 0) {//满足生成异常条件
throw new MyException("id 不小于 0"); // 抛出自定义异常
}else {
this.id = id;
}
}
public static void main(String[] args) {
Student s = new Student();
s.regist(-100);
}
}
/*
Exception in thread "main" javaSE.MyException: id 不小于 0
at javaSE.Student.regist(Student.java:9)
at javaSE.Student.main(Student.java:18)
*/
try-catch-finally
异常执行的顺序.
public class ExceptionTest {
static void method1() {
try{
System.out.println("try内部");
throw new RuntimeException("制造异常");
}finally {
System.out.println("finally内部");
}
}
static void method2() {
try{
System.out.println("try内部");
throw new RuntimeException("制造异常");
}catch(Exception e) {
// e.printStackTrace();
System.out.println("catch内部");
}finally {
System.out.println("finally内部");
}
}
public static void main(String[] args) {
ExceptionTest.method1();//只有try-finally,及包含手动抛出异常;try内部 --> finally内部 --> "制造异常"
//ExceptionTest.method2();//try-catch-finally,处理手动抛出的异常;try内部 --> catch内部 --> finally内部
}
}
总结.
- 捕获异常
try
– 执行可能产生异常的代码catch
– 捕获异常finally
– 无论是否发生异常,代码总被执行
- 抛出异常
throw
- 异常的生成阶段:手动抛出异常对象
- 声明异常
throws
- 异常的处理方式:声明方法可能要抛出的各种异常类
throw
和throws
区别.
throw
:表示抛出一个异常对象,生成对象的过程,声明在方法体内
throws
:属于异常处理的一种方式,声明在方法的声明处。