Java异常
# Java异常
# 概述
异常机制提供了程序退出的安全通道。当出现错误后,程序执行的流程发生改变,程序的控制权转移到异常处理器
Java类库的每个包中都定义有异常类,所有的异常类都是 Throwable
类 的子类,有两个子类分别是 Error类、Exception类
Error类 是描述java运行系统中的内部错误以及资源耗尽的错误,属于较为致命的错误
Exception类 是可以通过捕捉处理使程序继续运行,属于非致命的错误
# Throwable异常
Throwable类 是所有错误和异常
构造方法
Throwable() Throwable(String message) Throwable(String message , Throwable cause) Throwable(Throwable cause)
message: 详细信息(getMessage() 提供) cause: 原因(getCause() 提供)
方法
返回 | 方法 | 说明 |
---|---|---|
void | addSuppressed(Throwable exception) | 追加指定异常(有抑制的异常的作用) |
Throwable | fillInStackTrace() | 执行堆栈跟踪 |
Throwable | getCause() | 获取原因,未知 null |
String | getLocalizedMessage() | 创建此可抛出的本地化描述 |
String | getMessage() | 获取 异常详细,未知 null |
StackTraceElement[] | getStackTrace() | 获取堆栈跟踪信息的数组 |
Throwable[] | getSuppressed() | 获取所有被抑制的异常的数组 |
Throwable | initCause(Throwable cause) | 更改原因 |
void | printStackTrace() | 异常打印至错误流 |
void | printStackTrace(PrintStream s) | 异常打印至字节流 |
void | printStackTrace(PrintWriter s) | 异常打印至字符流 |
void | setStackTrace(StackTraceElement[] stackTrace) | 设置堆栈元素 |
String | toString() | 简短描述错误 |
# 常见异常
异常类 | 说明 |
---|---|
ClassCastException | 类型转换异常类 |
ClassNotFoundException | 没找到相应类异常 |
ArithmeticException | 算术条件异常 |
ArrayIndexOutOfBoundsException | 数组索引越界异常 |
ArrayStoreException | 数组中包含不兼容的值抛出的异常 |
SQLException | 操作数据库异常类 |
NullPointerException | 空指针异常 |
NoSuchFieldException | 字段未找到异常 |
NoSuchMethodException | 方法未找到抛出的异常 |
NumberFormatException | 字符串转换为数字抛出的异常 |
NegativeArraySizeException | 数组长度为负异常 |
StringIndexOutOfBoundsException | 字符串索引超出范围抛出的异常 |
IOException | 操作输入流和输出流时异常 |
IllegalAccessException | 不允许访问某类异常 |
InstantiationException | 当应用程序试图使用Class类中的newInstance()方法创建一个类的实例,而指定的类对象无法被实例化时,抛出该异常 |
EOFException | 文件已结束异常 |
FileNotFoundException | 文件未找到异常 |
# 捕捉异常
# try-catch 异常
try{
被捕获代码的区块
}catch(异常类型 e){
对异常处理的区块
}catch(异常类型 e){
对异常处理的区块
}catch(异常类型 e){
对异常处理的区块
}finally{
最后运行的区块
}
try: 语句用来存放可能发生异常的语句 catch: 激发被捕获的异常类型 finally: 异常处理的最后运行的区域
finally语句不会执行情况:
- 在finally语句块中发生了异常
- 在前面的代码中使用了
System.exit()
(退出程序) - 程序所在的线程死亡(运行时终止程序)
- 关闭CPU
# try-with-resources异常
try-with-resources异常是JDK9的新功能,
- try 块没有发生异常,自动调用 close 方法
- try 块 发生异常,然后自动调用 close()方法,如果 close 也发生异常,close() 方法的异常会在catch 中被压制,但是你可以在catch块中,用
Throwable.getSuppressed
方法来获取到压制异常的数组
点击代码示例* (try-with-resources 异常)
# 自定义异常
创建API中没有的异常,自定条件的异常
使用步骤:
- 创建自定义异常类
- 在方法中通过 throw 关键字 抛出异常对象
- 如果在当前抛出异常的方法中处理异常,可以使用 try-catch语句块捕获并处理,否则在方法的声明处通过 throws关键字 指明要抛出给方法调用者的异常
- 在出现异常方法的调用者中捕获并处理异常
class 自定义异常类 extends 已有的异常类{···}
# 抛出异常
方法出现异常,又不想在当前方法处理,则可以用 throws、throw 关键字 在方法中抛出异常
# throws 抛出异常
throws将代码中可能产生的异常交给上一级处理,直到处理异常 try-catch 语句调用 ,否则调用的那个方法也要加抛出的关键字已经方法类(一般使用于方法传参异常)
public void 方法名() throws 异常类型1,...,异常类型n{ }
被调用时:
try{
方法名();
}catch(异常类型 e){
e.printStackTrace();
}
# throw 抛出异常
手动制造异常。程序运行到throw语句时立即终止程序,不会执行后面的语句
使用throw抛出异常的前提
# 异常的使用原则
提高程序的安全性,控制流程状况以及异常修复!
- 不要怱略捕捉到的异常
- 不要过度使用异常
- 不要使用过于庞大的 try-catch语句
- 子类抛出的异常不能比父类高级(RuntimeException不受此约束)
- 一个方法被覆盖时,覆盖它的方法必须抛出相同的异常或异常的子类
# 代码索引
# Throwable异常
# Deme类
public class Demo {
public static void main(String[] args){
MyTest myTest = new MyTest();
try {
myTest.arithmeticException();
} catch (Exception e) {
Throwable throwable = new Throwable(e);
//追加异常
e.addSuppressed(new NullPointerException());
System.out.println("e.getMessage() => "+throwable.getMessage());
System.out.println("e.getCause() => "+throwable.getCause());
System.out.println("e.toString() => "+ throwable.toString());
StackTraceElement[] ste = throwable.getStackTrace();
System.out.println("所有堆栈跟踪:");
for(StackTraceElement tmp : ste){
System.out.println(tmp);
}
//打印 e 所有异常的错误流
e.printStackTrace();
}
}
}
# MyTest类
public class MyTest{
//异常测试
//算术异常
public void arithmeticException() throws ArithmeticException{
System.out.println("MyTest : 调用 arithmeticException()");
throw new ArithmeticException("arithmeticException() : ArithmeticException!!!");
}
//类型转换异常类
public void classCastException() throws ClassCastException{
System.out.println("MyTest : 调用 classCastException()");
throw new ClassCastException("classCastException() : ClassCastException!!!");
}
//字段未找到异常
public void noSuchFieldException() throws NoSuchFieldException{
System.out.println("MyTest : 调用 noSuchFieldException()");
throw new NoSuchFieldException("noSuchFieldException() : NoSuchFieldException!!!");
}
//空指针异常
public void nullPointerException() throws NullPointerException{
System.out.println("MyTest : 调用 nullPointerException()");
throw new NullPointerException("nullPointerException() : NullPointerException!!!");
}
//异常
public void exception()throws Exception{
System.out.println("MyTest : 调用 exception()");
throw new Exception("exception() : Exception!!!");
}
}
# try-catch 异常捕捉
public class Demo {
public static void main(String[] args) {
try{
int i = 1/0;
}catch (Exception e){
//输出异常错误性质
System.out.println(e.getMessage());
System.out.println("--");
//输出异常类型和性质
System.out.println(e.toString());
System.out.println("--");
//输出异常类型、性质、栈层(出现位置不定)
e.printStackTrace();
System.out.println("--");
}finally{
System.out.println("END.....");
}
}
}
/*
/ by zero
--
java.lang.ArithmeticException: / by zero
--
--
END.....
java.lang.ArithmeticException: / by zero
at Demo.main(Demo.java:5)
*/
# try-with-resources 异常
# Deme类
public class Demo {
public static void startTest(){
MyTestB myTestB = new MyTestB();
try(MyTestA myTestA = new MyTestA() ; myTestB){
myTestA.test();
//myTestA 中的 test 制造异常
myTestB.test();
}catch (Exception e){
System.out.println("Main : Exception!!!");
System.out.println("try异常 : ");
//获取try异常 : getMessage()
System.out.println(e.getMessage());
//获取抛出异常 : getSuppressed()
//Throwable异常的超父类
Throwable[] suppressed = e.getSuppressed();
System.out.println("抛出异常 :");
for(Throwable tmp : suppressed){
System.out.println(tmp.getMessage());
}
}
}
public static void main(String[] args) throws Exception{
startTest();
}
}
/*
MyTextA : 调用 test()
MytestB: 关闭 close()
MyTextA: 关闭 close()
Main : Exception!!!
try异常 :
MyTextA : test() !!!
抛出异常 :
MytestB: close() ClassNotFoundException!!!
MyTextA: close() ClassNotFoundException!!!
*/
# MyTestA类
import java.io.IOException;
public class MyTestA implements AutoCloseable {
public void test()throws IOException{
System.out.println("MyTextA : 调用 test() ");
//制造异常
throw new IOException("MyTextA : test() !!!");
}
@Override
public void close() throws Exception {
//提示关闭流
System.out.println("MyTextA: 关闭 close()");
//制造异常
throw new ClassNotFoundException("MyTextA: close() ClassNotFoundException!!!");
}
}
# MyTestB类
import java.io.IOException;
public class MyTestB implements AutoCloseable {
public void test()throws IOException{
System.out.println("MytestB : 调用 test() ");
//制造异常
throw new IOException("MytestB : test() !!!");
}
@Override
public void close() throws Exception {
//提示关闭流
System.out.println("MytestB: 关闭 close()");
//制造异常
throw new ClassNotFoundException("MytestB: close() ClassNotFoundException!!!");
}
}
# 自定义异常
public class Demo {
public static void main(String[] args) {
orangutan xingxing = new orangutan();
bird niao = new bird();
key yaoshi = new key();
//No.1
try {
if (!(xingxing instanceof Animals)){
throw new CustomException("非动物"+xingxing);
}
System.out.println("开始1");
} catch (CustomException e) {
e.printStackTrace();
}
//No.2
try {
if (!(niao instanceof Animals)){
throw new CustomException("非动物"+niao);
}
System.out.println("开始2");
} catch (CustomException e) {
e.printStackTrace();
}
//No.3 类型错误
try {
throw new CustomException("非动物:"+yaoshi);
} catch (CustomException e) {
e.printStackTrace();
}catch (Exception e){
e.printStackTrace();
}
}
}
//动物类
class Animals{ }
//猩猩
class orangutan extends Animals{ }
//鸟
class bird extends Animals { }
//物品类
class Items{ }
//钥匙
class key extends Items{ }
//自定义异常类 继承异常类
class CustomException extends Exception{
public CustomException(String message){
super(message);
}
}
/*
开始1
开始2
CustomException: 非动物:key@133314b
at Demo.main(Demo.java:30)
*/
# throws 抛出异常
public class Demo {
//抛出中断异常 throws 抛出
public static void show() throws InterruptedException ,ArithmeticException{
for (int i = 0; i <= 10 ; i++) {
System.out.println(i);
Thread.sleep(1000);
if (i == 5){
i-=5;
int s = 1/i;
}
}
}
public static void (String[] args) {
//获取方法中的异常
try {
show();
//终止异常
} catch (InterruptedException e) {
System.out.println("show()方法抛出终止异常");
//算术异常
}catch (ArithmeticException e) {
System.out.println("show()方法抛出算术异常");
//异常
}catch (Exception e) {
System.out.println("show()方法抛出异常");
}
}
}
/*
0
1
2
3
4
5
show()方法抛出算术异常
*/
# throw 抛出异常
public class Demo2 {
public static void main(String[] args) 想·{
int a = 1 , b = 0 ;
if (b == 0){
//强制中断
throw new NullPointerException("b 为 0");
}
int s = a / b ;
}
}
/*
java.lang.NullPointerException: b 为 0
at Demo2.main(Demo2.java:7)
*/