1. 什么是异常
2. 异常的分类
- **检查性异常:**最具代表的检查性异常是用户错误或问题引起的异常,这是程序员无法预见的。例如要打开一个不存在文件时,一个异常就发生了,这些异常在编译时不能被简单地忽略。
- 运行时异常: 运行时异常是可能被程序员避免的异常。与检查性异常相反,运行时异常可以在编译时被忽略。
- 错误ERROR: 错误不是异常,而是脱离程序员控制的问题。错误在代码中通常被忽略。例如,当栈溢出时,一个错误就发生了,它们在编译也检查不到的。
3. 异常的体系结构
4. Error
5. Exception
6. 捕获异常
-
使用 try 和 catch 关键字可以捕获异常。try/catch 代码块放在异常可能发生的地方。try/catch代码块中的代码称为保护代码,
-
finally 关键字用来创建在 try 代码块后面执行的代码块。无论是否发生异常,finally 代码块中的代码总会被执行。
-
快捷键:Ctrl+alt+T
try{
// 程序代码
}catch(异常类型1 异常的变量名1){
// 程序代码
}catch(异常类型2 异常的变量名2){
// 程序代码
}finally{
// 程序代码
}
代码实例
package com.exception;
public class Test {
public static void main(String[] args) {
int a = 1;
int b;
b = 0;
//假设要捕获异常,从小到大
try {//try 监控区域
System.out.println(a/b);
} catch(ArithmeticException e){//catch(想要捕获的异常类型) ~捕获异常
System.out.println("异常,变量值b不能为0");
} catch (Error e2){
System.out.println("Error");
} catch (Exception e3){
System.out.println("Exception");
} catch (Throwable e4){
System.out.println("Thorwable");
} finally {//处理善后工作
System.out.println("finally");
}
//finally 可以不要finally,finally一般用于IO流,资源,关闭
}
}
/*输出结果为:
异常,变量值b不能为0
finally
*/
快捷键:Ctrl+alt+T
package com.exception;
public class Test {
public static void main(String[] args) {
int a = 1;
int b;
b = 0;
//快捷键:Ctrl+alt+T
try {
System.out.println(a/b);
} catch (Exception e) {
/**/ //System.exit(1);//结束程序 /**/
e.printStackTrace();//打印错误的栈信息
} finally {
}
//finally 可以不要finally,finally一般用于IO流,资源,关闭
}
}
注意:代码中的System.exit(int status):不管status为何值都会退出程序(即结束当前正在运行的java虚拟机),但是只有在status等于0,即System.exit(0);的时候整个程序正常退出。当status为除0之外的数字时都视为程序的不正常退出。
示例:
-
在一个if-else判断中,如果我们程序是按照我们预想的执行,到最后我们需要停止程序,那就使用System.exit(0),
-
而System.exit(1)一般放在catch块中,当捕获到异常,需要停止程序,我们使用System.exit(1)。)
7. 抛出异常
-
throw : 将产生的异常抛出(强调的是动作),抛出的既可以是异常的引用,也可以是异常对象。(位置: 方法体内)
-
throws : 如果一个方法可能会出现异常,但没有能力处理这种异常,可以在方法声明处用throws子句来声明抛出异常。用它修饰的方法向调用者表明该方法可能会抛出异常(可以是一种类型,也可以是多种类型,用逗号隔开)(位置: 写在方法名 或方法名列表之后 ,在方法体之前。)
-
注意 : 调用可能会抛出异常的方法,必须添加try-catch代码块尝试去捕获异常 或者 添加throws 声明 来将异常 抛出给更上一层的调用者进行处理。
-
这里需要注意一个细节:新的异常包含原始异常的所有信息,根据这个我们可以去追溯最初异常发生的位置,
代码实例
package com.exception;
public class Test02 {
public static void main(String[] args) {
int a = 1;
int b;
b = 0;
try {
new Test02().test(1,0);
} catch (ArithmeticException e) {
e.printStackTrace();//打印错误的栈信息
}
}
//假设在这方法中,处理不了这个异常,方法上抛出异常~thorws
public void test(int a, int b) throws ArithmeticException{//thorws
if (b == 0) {//主动的抛出异常,一般在方法中使用~thorw
throw new ArithmeticException();//throw
}
}
}
8. 自定义异常
创建自定义异常类
package com.exception;
//自定义的异常类(传递的数字不能大于10)
public class MyException extends Exception {
//传递数字 > 10;
private int detail;
public MyException(int a){//消息的构造器,快捷键:alt+insert
this.detail = a;
}
//toString:异常的打印信息 快捷键:alt+insert
@Override
public String toString() {
return "MyException{" + "-->异常数字是:" + detail + '}';
}
}
存在异常的方法
package com.exception;
public class Test03 {
//可能会存在异常的方法
static void test(int a) throws MyException{
System.out.println("传递的参数为:"+a);
if(a>10){
throw new MyException(a);//抛出
}
System.out.println("没有异常");
}
public static void main(String[] args) {
try {
test(11);
} catch (MyException e) {
System.out.println(e);
}
}
}
/*输出结果为:
传递的参数为:11
MyException{-->异常数字是:11}
*/