异常
java语言采用异常来处理系统级和应用程序级的错误状态,它是一种结构化的、统一的和类型安全的处理机制。
在程序运行过程中,如果产生错误,则抛出异常;通过try语句来定义代码块,运行可能抛出异常的代码;通过catch语句,可以捕获特定的异常并执行相应的处理;通过finally语句,可以保证即使产生异常(处理失败),也可以在事后清理资源等。
异常类
在程序运行过程中,如果某个方法中出现了错误,则可以创建一个异常对象(exception object),并通过throw语句把创建的异常抛出给系统运行时,即程序终止正常执行流程,转而执行异常处理流程。
- 异常对象是异常类的对象实例。
- java异常类均继承于java.lang.Throwable。
- java异常类层次结构:
异常 | 描述 |
---|---|
ArithmeticException | 当出现异常的运算条件时,抛出此异常。(数学异常)例如,一个整数"除以零"时,抛出此类的一个实例。 |
ArrayIndexOutOfBoundsException | 用非法索引访问数组时抛出的异常。(数组下标异常)如果索引为负或大于等于数组大小,则该索引为非法索引。 |
IllegalArgumentException | 抛出的异常表明向方法传递了一个不合法或不正确的参数。 |
IndexOutOfBoundsException | 指示某排序索引(例如对数组、字符串或向量的排序)超出范围时抛出。 |
NullPointerException | 当应用程序试图在需要对象的地方使用 null 时,抛出该异常(空指针异常) |
NumberFormatException | 数据类型异常 |
- 错误异常类
Error类及其子类通常用于程序无法处理的错误,例如StackOverflowError等。
- 错误异常一般由java虚拟机抛出,并有java虚拟机捕获。
- 这些异常发生时,java虚拟机一般会选择在控制台打印相应的错误信息,并终止运行。
- 运行时异常类
RuntimeException类及其子类,称为运行时异常。
- 运行时异常类一般由程序逻辑错误引起。
- 在程序代码中可以选择捕获处理这些异常,也可以不捕获处理。
- 编译时异常类
Exception类及其子类(除RuntimeException类及其子类),称为非运行时异常类。
- 非运行时异常类是必须进行处理的异常,如果不处理,程序将不能编译通过。
- 非运行时异常类一般是java类库包含特定应用的异常,例如java.io.IOException、SQLException等,以及用户自定义的继承于Exception异常。
抛出异常
- Java虚拟机抛出异常
举例:
int a = 10;
int b = 10/0;
System.out.println(b);
output: 数学异常,除数不能为0
- 程序代码抛出异常
举例:
//手动抛出异常,可以给异常带有参数
String str = null;
if(str == null) {
throw new NullPointerException("str==null");
}
捕获异常
当程序中某个方法抛出异常后,Java虚拟机通过调用堆栈查找相应地异常捕获程序。如果找到匹配的异常捕获程序(即调用堆栈中的某方法使用try…catch语句捕获处理),则执行相应的处理程序,即执行catch语句块。如果虚拟机中没有相应匹配的异常捕获程序,则java虚拟机捕获处理异常。
举例:
- 使用 try 和 catch 关键字可以捕获异常。
try/catch 代码块放在异常可能发生的地方。try/catch 代码块放在异常可能发生的地方。try/catch代码块中的代码称为保护代码,使用 try/catch 的语法如下:
try
{
// 程序代码
}catch(ExceptionName e)
{
//Catch 块
}
举例:
public static void main(String[] args) {
try {
int[] array = {1,2,3,4};
System.out.println(array[5]);
}catch (ArrayIndexOutOfBoundsException e){
System.out.println("数组越界");
e.printStackTrace();
}
}
output:
3. 多重捕获块
一个 try 代码块后面跟随多个 catch 代码块的情况就叫多重捕获。
public static int division (int num1, int num2 ){
return num1 / num2 ;
}
public static void Calculator()
//这里已经处理了异常,不需要再声明异常了
//如果加了声明,当前函数就不处理了,调用该函数的一方进行处理。
{
Scanner scan = new Scanner ( System. in );
try {
int num1 = scan .nextInt () ;
int num2 = scan .nextInt () ;
int result = division (num1 , num2 ) ;
System.out.println( "result:" + result) ;
} catch (ArithmeticException e) {
System.out.println("ArithmeticException 异常");
e.printStackTrace();
} catch (InputMismatchException e) {//输入有误的时候
System.out.println("InputMismatchException 异常");
e.printStackTrace();
} finally {
scan.close ();//资源的释放,关闭相应的流
}
}
public static void main(String[] args) {
Calculator();
}
output:
-
输入10,2 测试:
-
输入字符测试:
-
输入10,0测试:
举例:
//try catch块与输出流结合
public static void main(String[] args) throws IOException {//输出流,写入
FileOutputStream file1 = null;//创建一个FileOutputStream类的对象
File file = new File("G:\\1.txt");//创建一个File类对象,表明要写入的文件位置。
// 输出的物理文件可以不存在,当执行过程中,若不存在,会自动的创建。若存在,会将原有的文件覆盖
file1 = new FileOutputStream(file);//
try {
file1.write(new String("I love programming").getBytes());//写入的操作
}catch (IOException e){
e.printStackTrace();
}finally {
if (file1 != null){
try {
file1.close();//关闭输出流
}catch (IOException e){
e.printStackTrace();
}
}
}
}
声明异常和自定义异常
- java中通过throws声明某个方法抛出的各种异常,可以同时声明多个异常,用逗号隔开。声明异常只是表明有可能会有异常抛出。
public static void Select()throws NullPointerException{
throw new NullPointerException("这是一个空指针异常。");
}
public static void main(String[] args) {//6
Exception c = new Exception();
try {
c.Select();
}catch (java.lang.Exception e){
e.printStackTrace();
}
}
- 何时需要自定义异常?
当JDK中的异常类型不能满足程序的需要时,可以自定义异常。(一般自定的时候都是需要异常帮程序做一些事情的时候)
- 自定义异常类一般包括两个构造方法:一个是默认构造方法;另一个是带String参数的构造方法(详细描述信息,超类Throwable的toString() 方法将打印此信息,可以方便程序调试)。
- 自定义异常类的命名规则一般以Exception为后缀。
1、定义一个异常
2、编写构造方法继承父类的实现
3、实例化自定义异常类型
4、使用throw抛出
class MyException extends Exception{
public MyException(String lili){//自定义异常类,继承Exception类
super();//默认构造函数
}
}
public class Exception extends Throwable {
public static void fun1() throws MyException{
System.out.println("throw MyException");
throw new MyException("lili");//可以给参数
}
public static void main(String[] args) {
try {
Exception.fun1();
}catch (MyException e) {
System.out.println("MyException caugth it");
e.printStackTrace();
}
}
}