JavaSE基础(十)——异常机制
前言
在程序运行过程中,可能会出一些编译软件无法检查出来的错了,这些错误在运行阶段可能会因为某种情况(可能是数组下标越界、内存溢出等)而出现程序中断的问题,这些出现的问题就是异常。
本篇笔记记录的就是认识这些异常并在某种程度上解决一些在编码阶段就能避免的异常。
异常
异常通俗来讲就是一些例外情况,我们在编码过程中可以通过分支结构或者完善逻辑来解决,但是我们总有考虑不到的情况导致程序出现异常。同时,有些异常可以直接归类,进行统一处理,这就是异常以及异常的处理逻辑。
举个例子:
public static void main(){
a();
}
public static void a(){
b();
}
public static void b(){
a();
}
上述代码会因为程序陷入死循环,死循环会在某了临界点占用JVM全部的内存,从而导致内存溢出异常。
【注】:内存溢出异常大家可能理解不到位,这个涉及到Java虚拟机(JVM)中底层运行规则,后续会有讲解。大家现在可以简单的理解为,每调用一次方法,都会在虚拟机中开辟一个空间来执行相关操作,即使同名方法也会这样。当循环到一定程度时,虚拟机的内存你就会被这些调用方法申请的空间占满,从而导致没有空间继续支持程序运行。
异常体系结构
Java语言中,异常有很多种,大体分为两类:检查时异常、运行时异常。具体如下:
图片中Error是Java运行时的错误,这种错误一般都是虚拟机运行错误,可能与我们没有太大关系,因为我们在敲代码的时候我们基本无法避免出现。
Exception(异常),共分为两类:
- IOException:IO异常,在后续介绍到IO流的时候会有详细说明,暂时可以理解为读取或写入文件失败;
- RuntimeException:运行时异常,其中有很多种细分的异常,图片中仅仅记录了常见的异常。
Exception中最重要的分支就是运行时异常,下面为异常的具体含义:
- ArrayIndexOutOfBoundsException:数组下标越界,操作数组的时候使用了不在数组定义范围内的数组下标;
- NullPointerException:空指针异常,引用或者调用方法的时候没有找到对应的目标;
- ArithmeticException:算术异常,典型代表就是0作为除数;
- MissingResourceException:丢失资源;
- ClassNotFoundException:找不到类。
以上异常一般都是由程序逻辑错误引起的,一般可以通过缜密的逻辑来避免。这些异常一旦出现或者有可能出现就一定要处理,否则可能编译不通过。
Error与Exception的区别
Error一般是灾难性的错误,是程序无法控制和处理的,当出现这些异常的时候,JVM通常会选择终止线程(停止执行);
Exception一般是可以通过缜密的逻辑以及相应的代码来处理的,同时程序员应该在程序中尽可能的去处理这些异常。
异常捕获及处理
异常处理机制包括以下两个步骤:
- 抛出异常;
- 捕获异常。
异常处理关键字:
- try:尝试处理某些异常,try包含的代码扩中出现的异常将会在catch中捕获并解决;
- catch:捕获异常,并尝试解决;
- finally:在catch没有捕获到相应异常或者没有异常时处理的最终解决手段(finally无论如何都会被执行,即使在catch中使用return来结束执行也必须执行finally中的代码);
int a = 1;
int b = 0;
try{
int c = a/b;
// catch中的参数可以使用Throwable来捕获,该参数位置就是我们想要捕获的异常
}catch(ArithmeticException e){
System.out.println("程序出现异常,0不能作为除数");
}
- throw: 主动抛出异常,一般在方法中使用;
int a = 1;
int b = 0;
if(b = 0){
// 主动抛出算术异常,并结束程序运行
throw new ArithmeticException();
}
int c = a/b;
- throws:用在方法声明上使用,抛出异常并结束程序运行
public void action() throws ArithmeticException{
int a = 1;
int b = 0;
int c = a/b;
}
自定义异常
Java内置的异常类可以描述大部分异常情况,除此之外,程序员还可以自定义异常类来解决一些问题。在自定义异常类的时候需要继承Exception类。
public class MyException extends Exception{
// 该异常类处理数据小于0的情况
private int detail;
public MyException(){
}
public MyException(int detail){
this detail = detail;
}
// 这个方法是重写的
@Override
public String toString(){
return "异常啦" + detail;
}
}
public class Demo{
public static void main(String[] args){
int a = -1
System.out.println("传递参数为" + a);
if(a < 0){
throw new MyException(a);
}
System.out.println("没有问题");
}
}
总结
异常一个比较复杂的知识点,在笔记中并没有记录很多,因为异常以及处理是经验问题,每个人的编码习惯以及个人理解都不同,所以这个问题我个人认为是走一步看一步。
但是一定要养成良好的编程习惯,去学习标准的编程规范。