Throwable是所有异常和错误的父类,有2个子类
* Error 错误:
* 程序中不做处理
* 例如由于内存条太小导致内存溢出
* Exception 异常
* 运行期异常
* 运行时发生的异常,程序中不做处理
* 一般是因为代码逻辑不严谨导致
* 例如 int num = 1/0;
* 编译期异常
* 非运行期异常都是编译期异常
* 程序中一定要处理,否则编译过不掉
* 常用方法
* getMessage():异常描述字符串
* toString():异常类的包名:异常描述字符串(getMessage())
* printStackTrace():第一行调用toString(),后面打印异常出现的位置
* printStackTrace(printStream s):调用printStackTrace且可以将异常信息写到文件中
处理编译期异常方式一:
try {
可能出异常的代码1;
可能出异常的代码2;
} catch(异常类名1 异常变量名1){
处理方式1;
} catch(异常类名2 异常变量名2){
处理方式2;
}
说明:
* 一个try可以有多个catch,父类要放在后面
* try中的代码一旦出现异常,try中出现异常代码后面的代码不继续执行,直接进入异常处理
处理编译期异常方式二:
try {
可能出异常的代码1;
可能出异常的代码2;
} catch(异常类名1 异常变量名1 | 异常类名2 异常变量名2...){
处理方式;
}
说明:
* 这种处理异常的方式是jdk1.7的新特性
* catch中的多个异常必须是平级关系
异常处理的流程:
* try中的代码出现异常,即创建了一个异常对象,到catch中去匹配
* catch中的异常
处理编译期异常方式三:throws
* 在方法的括号后面使用throws 异常类名抛出异常
* 如果方法声明后抛出了一个运行期异常则不需要处理,例如除数为0异常
* 如果方法声明后抛出了一个编译期异常则必须要处理,例如日期转换日常
处理编译期异常方式四:throw
* 抛出一个运行期异常
public class MyTest {
public static void main(String[] args) {
//因为devide方法中使用throw抛出的是一个运行期异常,调用该方法时可以不处理
devide(10,0);
}
public static void devide(int a,int b) {
if (b == 0) {
throw new ArithmeticException();
} else{
System.out.println(a/b);
}
}
}
* 抛出一个编译期异常
public class MyTest {
public static void main(String[] args) {
try {
//因为devide方法中使用throw抛出的是一个编译期异常,调用该方法必须要处理异常
devide(10,0);
} catch (Exception e) {
e.printStackTrace();
}
}
public static void devide(int a,int b) throws Exception {
if (b == 0) {
throw new Exception();
} else{
System.out.println(a/b);
}
}
}
throws和throw的区别
* throws出现在方法的括号后面,后面可以跟一个或多个类名,表示出现异常的可能,不一定会出现
* throw出现在方法内部,后面只能跟一个异常对象名,表示已经出现异常
* throw抛出的是运行期异常,调用该方法可以不处理
* throw抛出的是编译期异常,调用该方法必须处理
finally
* finally中的代码一定会执行
* 特殊情况:执行到finally之前jvm退出,例如System.exit(0);
* 用于释放资源
final,finally,finalize的区别
* final:最终的意思,可以修饰变量,方法,类
* finally:异常处理的一部分,里面的代码一定会执行,除非jvm退出
* finalize:是Object的一个方法,用于垃圾回收
catch中有return语句时finally中代码的执行时机
情景一:catch中有return,finally中没有return
* catch中有return时会先形成return通道
* 再执行finally中的语句
* 再返回catch中继续执行return语句
* finally中代码不会影响return语句中变量的值
* 如下代码:
* catch捕捉到异常
* a = 30;
* 执行return a;返回通道形成并打开准备返回值30
* return执行到一半,值30还没有返回去,发现有finally代码
* 先执行finally中的代码
* finally中的代码执行完成,虽然finally中将a赋值为40但是因为返回通道已经形成,值不会改变,所以继续返回值30
public class MyTest {
public static void main(String[] args) {
System.out.println(getInt());
}
public static int getInt(){
int a = 10;
try {
System.out.println(a/0);
a = 20;
} catch (ArithmeticException e) {
a = 30;
return a;
} finally{
a = 40;
}
return a;
}
}
情景二:catch中有return,finally中也有return
* catch中有return时会先形成return通道
* 再执行finally中的语句
* finally中有return语句,则不再返回catch
* 返回的也是finally中的值
* 如下代码:
* catch捕捉到异常
* a = 30;
* 执行return a;返回通道形成并打开准备返回值30
* return执行到一半,值30还没有返回去,发现有finally代码
* 先执行finally中的代码
* finally中的代码执行完成,发现有return语句,直接return,不再返回catch,所以最后返回值40
public class MyTest {
public static void main(String[] args) {
System.out.println(getInt());
}
public static int getInt(){
int a = 10;
try {
System.out.println(a/0);
a = 20;
} catch (ArithmeticException e) {
a = 30;
return a;
} finally{
a = 40;
return a;
}
}
}
try{} catch(){} finally{}格式变形
* try...catch
* try...catch...catch
* try...catch...catch...finally
* try...finally
自定义异常:
继承Exception
继承RuntimeException
继承关系中的异常
* 子类在继承父类时必须抛出和父类异常相同的异常或父类异常的子类
* 子类不能抛出父类没有的异常
* 被覆盖的方法中如果没有抛出异常,那么子类的方法中不可以抛出异常,只能try...catch
001-SE-0006-异常
最新推荐文章于 2022-09-06 13:57:29 发布