目录
- 1. 异常的分类
- 1.1 运行时异常
- 1.2 编译时异常
- 2. 异常的抛出
- 2.1 throw
- 2.2 throws
- 3. 异常的捕获
- 3.1 try-catch
- 3.2 finally
- 4. 异常执行的过程
- 5. 自定义异常
在Java中,异常(Exception)是指程序发生不正常的行为,异常其实就是一个一个的类。
1. 异常的分类
Java中,异常有很多种,每一种异常都是一个类,为了更好地管理这些类Java引入了一个异常体系,如图
Exception是Throwable的子类,也就是说Throwable是异常体系中最顶层的类。Throwable还有一个子类叫Error,Error指的是错误,是指程序发生无力回天的错误(虚拟机内部错误、内存资源耗尽),如栈溢出错误。异常可以通过程序员的处理让程序继续执行,异常可以分为两种:运行时异常、编译时异常。
1.1 运行时异常
运行时异常是指程序运行之后出现的异常,也叫非受查异常,RuntimeException及其子类都属于运行时异常。例如空指针异常:
public static void main(String[] args) {
int[] array = null;
System.out.println(array.length);
}
1.2 编译时异常
编译时异常是指代码在编译时发生的异常,也叫受查异常,如:CloneNotSupportedException(克隆不支持异常)
A类没有实现Cloneable接口,在程序还没运行之前就报错了,这就是编译时异常。
2. 异常的抛出
2.1 throw
当程序出现异常,程序会自动抛出异常,程序猿们也可以使用throw手动抛出异常,语法是:throw new xxxException;
比如:抛出一个RuntimeException
throw new RuntimeException();
2.2 throws
throws是异常的声明,表示在这个地方有异常会发生,但是没有处理这个异常。
如:在main方法中声明CloneNotSupportedException异常
public static void main(String[] args) throws CloneNotSupportedException {
//...........
}
3. 异常的捕获
前面说的都是异常的抛出和声明,但是并没有处理异常,那么如何处理异常?可以使用try-catch
3.1 try-catch
try的意思是尝试,catch的意思是抓住/捕获。
try-catch的语法格式如下:
try {
//可能发生异常的代码块
} catch (要捕获的异常类型) {
//处理异常的代码块
}
例如:
public static void main(String[] args) {
try {
int[] array = null;
System.out.println(array.length);
} catch (NullPointerException e) {
//......处理异常的代码
e.printStackTrace();//printStackTrace可以打印堆栈的信息
}
}
try-catch也支持下面几种用法:
try {
//.....
} catch (NullPointerException e) {
//.....
} catch (ArithmeticException e) {
//.....
}
try {
//.....
}
catch (NullPointerException | ArithmeticException e) {
//.....
}
注意事项:
如果包含多个catch且异常有父子类关系,父类必须放在最后。
如:
Exception是所有异常的父类,应该将Exception放在最后。
try {
//.....
} catch (NullPointerException e) {
//.....
} catch (Exception e) {
}
3.2 finally
finally需配合try-catch使用,无论有没有发生异常,finally当中的语句都会执行。例如:
public static void main(String[] args) {
try {
int[] array = null;
System.out.println(array.length);
} catch (NullPointerException e) {
System.out.println("这里发生空指针异常!!!");
} finally {
System.out.println("finally语句");
}
}
运行结果:
4. 异常执行的过程
如图:
举个例子:
例子1:
下面代码会出现空指针异常,但是没有进行任何处理,程序直接终止,after不会被打印
public static void main(String[] args) {
int[] array = null;
System.out.println(array.length);
System.out.println("after");
}
运行结果:
例子2:
以下代码也会发生空指针异常,但是catch并没有这个类型,也就是说catch语句捕获不到空指针异常,此时会将异常交给Java虚拟机,程序直接终止,after也不会被打印
public static void main(String[] args) {
try {
int[] array = null;
System.out.println(array.length);
} catch (ArithmeticException e) {
System.out.println("发生算术异常!!!");
}
System.out.println("after");
}
运行结果:
例子3:
以下代码发生空指针异常,catch语句捕获到了这个异常,程序继续执行,after打印
public static void main(String[] args) {
try {
int[] array = null;
System.out.println(array.length);
} catch (NullPointerException e) {
System.out.println("发生空指针异常!!!");
}
System.out.println("after");
}
运行结果:
5. 自定义异常
虽然Java中有很多内置的异常类,但是并不能完全满足我们使用,能不能自己定义一种异常?完全可以!
我们可以模仿Java内置的异常来定义自己的异常类:
Java内置异常NullPointerException:
自定义异常:
public class MyException extends RuntimeException {
public MyException() {
super();
}
public MyException(String s) {
super(s);
}
}
注意事项:
1. 自定义的异常类名称尽量做到见名知意
2. 自定义异常一般继承Exception或RuntimeException
3. 如果自定义异常继承的是Exception,这个自定义的异常默认是受查异常
4. 如果自定义异常继承的是RuntimeException,这个自定义的异常默认是非受查异常
今天的内容就到这里,感谢老铁们的点赞收藏~