异常
异常指运行中出现了不期而至的状况,如:文件找不到,网络异常、非法参数等。
异常发生在程序运行期间,影响了正常的程序执行流程。
异常类别
异常主要分为三类:
-
检查性异常:常由用户输入引起,程序员无法预见
-
运行时异常:是可能被程序员避免的,运行时异常在编译时会被忽略
-
错误ERROR:错误不是异常,是脱离程序员控制的问题。错误在代码中常被忽略,在编译时不会被检查出来。如栈溢出时,发生错误
异常体系结构
Java把异常当作对象处理,定义了一个基类java.lang.Throwable
作为所有异常的超类。
在Java API中定义了许多异常类,这些类分为两类:错误ERROR和异常Exception
Error
Error类对象由Java虚拟机生成并抛出,大多数错误与代码编写者所执行的操作无关。
Java虛拟机运行错误(Virtual MachineError), 当JVM不再有继续执行操作所需的内存资源时,将出现OutOfMemoryError。这些异常发生时,Java虚拟机(JVM)一般会选择线程终止;
还有发生在虚拟机试图执行应用时,如类定义错误(NoClassDefFoundError) 、链接错误(LinkageError)。这些错误是不可查的,因为它们在应用程序的控制和处理能力之外,而且绝大多数是程序运行时不允许出现的状况。
Exception
在Exception分支中有一个重要的子类RuntimeException (运行时异常):
- ArraylndexOutOfBoundsException (数组下标越界)
- NullPointerException (空指针异常)
- ArithmeticException (算术异常)
- MissingResourceException (丢失资源)
- ClassNotFoundException (找不到类)等异常,这些异常是不检查异常,程序中可以选择捕获处理,也可以不处理
这些异常一般是由程序逻辑错误引起的,程序应该从逻辑角度尽可能避免这类异常的发生;
除了以上的异常,其余的被称为非运行时异常。
Error和Exception的区别
- Error通常是灾难性的致命的错误,是程序无法控制和处理的,当出现这些异常时,Java虚拟机(JVM)一般会选择终止线程;
- Exception通常情况下是可以被程序处理的,并且在程序中应该尽可能的去处理这些异常。
异常处理机制
异常处理关键字:try
、catch
、finally
、throw
、throws
捕获异常
捕获异常相关关键字:try
、catch
、finally
捕获异常代码:
try {
// try监控区域
可能发生异常的代码
} catch (要捕获的异常类型 异常名) {
捕获异常
} finally {
善后工作,一般用于关闭资源
}
try...catch知识点:
- 一个try可以有多个catch
- 若要捕获多个异常,必须按照从小到大去捕获,异常类型范围等级:Throwable > Error = Exception
- 范围最大的异常要写在最下面的catch中
- 在多重catch块后面,可以加一个
catch (Exception)
来处理可能会被遗漏的异常 - 尽量处理异常,不要简单的调用
printStackTrace()
打印输出 - 尽量添加finally语句块释放占用的资源
快速生成try...catch的快捷键:Win:ctrl + alt + T
,Mac:command + option + T
抛出异常
抛出异常关键字:throw
、throws
抛出异常代码:
if (b == 0){
throw new Exception();
}
抛出异常一般用在方法中,若方法中无法处理该异常,要在方法上通过throws
关键字抛出异常:
public void devide(int a, int b) throws Exception{
if (b == 0) {
throw new ArithmeticException();
} else {...}
}
在方法的后面使用throws
关键字对外声明该方法有可能发生异常,这样调用者在调用方法时,就明确地知道该方法有异常,并且必须在程序中对异常进行处理,否则编译无法通过
try {
System.out.println(new Demo02().divide(a, b));
} catch (Exception e) {
System.out.println("Exception");
}
自定义异常
使用Java内置的异常类可以描述程序中的大部分异常,此外,用户还可以自定义异常。
用户自定义异常类,需要继承Exception类。
自定义异常步骤:
- 创建自定义异常类
- 在方法中通过
throw
关键字抛出异常 - 若在当前抛出异常的方法中处理异常,可以使用
try- catch
语句进行捕获;否则在方法声明处通过throws
关键字指明要抛出给方法调用者的异常 - 调用者对出现可能异常的方法进行捕获和处理
自定义异常:
// 自定义异常类
public class MyException extends Exception {
// 定义抛出异常的提示信息
private int detail;
// 构造器
public MyException(int a) {
this.detail = a;
}
// toString:异常的打印信息
@Override
public String toString() {
return "MyException{detail=" + detail + '}';
}
}
使用自定义异常:
// 定义一个可能存在异常的方法
public void compare(int a) throws MyException{
System.out.println("in: " + a);
if (a > 0) {
throw new MyException(a);
}
System.out.println("success");
}
捕获异常并处理:
try {
new Demo03().compare(2);
} catch (MyException e) {
System.out.println("MyException: " + e); // e转换为字符串会自动调用toString()方法
}