异常
一、概念
1、基本概念
异常(Exception)本质就是不正常之意。主要指Java程序在运行期间产生的错误,程序编译通过并不代表着在运行时不会出错。
作用:通过异常提示信息可以快速的知道程序的问题,有助于开发者编写出更加健壮的程序,这是异常最主要的作用。
java.lang.Throwable类是java语言中 所有错误 和 异常 的超类。
- 其中,错误 使用 java.lang.Error 类 加以描述, 通常指比较严重的错误,无法编程解决;
只能重新启动程序,最典型的Error的异常是:OutOfMemoryError(内存溢出)
-其中,异常 使用 java.lang.Exception类 加以描述,通常是可以通过代码解决的小问题。
2、异常的分类
异常主要分为:一般性异常、RuntimeException
- IOException异常 和 其他异常类:也叫检测异常,出现了这种异常必须在程序里面显示的处理,否则程序无法编译通过
- RuntimeException :运行时异常,也叫非检测性异常。运行阶段发生。此种异常可以不用显示的处理,例如被0除异常,java没有要求我们一定要处理。
3、常见的几种异常
- 01. NullPointerException 空指针异常;
- 02. ClassCastException 类型强制转换异常
- 03. IllegalArgumentException 方法的参数错误:
- 04. IndexOutOfBoundsException 数组下标越界异常;
- 05. ArithmeticException 算术运算异常
- 06. NumberFormatException 字符串转换为数字异常:
- 07. FileNotFoundException 文件未找到异常
- 08. InstantiationException 实例化异常
- 09. ClassNotFoundException 指定的类不存在
- 10. IllegalAccessException 没有访问权限
4、JVM是如何处理异常的
但是当程序发生异常,且并没有手动对异常进行处理时,该异常会被JVM采用默认的方式处理。
- main方法自己将该问题处理,然后继续运行
- 自己没有针对的处理方式,只有交给调用main的JVM来处理,JVM有一个默认的异常处理机制。
- 例如上面出现的ArithmeticException,jvm在控制台里面打印出来了异常信息。
而默认的处理方式 就是:
- 打印 异常名称;
- 打印 异常信息;
- 打印 异常发生的位置;
- 并终止程序.5、 非检测性异常的处理方式
对于绝大多数的非检测性异常来说,只需要使用 if()条件对可能产生异常的代码进行判断处理,就可以避免异常的产生。
6、 检测性异常的处理方式: 1、异常的捕获 ; 2、 异常的抛出
6.1 异常的捕获
import java.io.FileInputStream;
import java.io.FileNotFoundException;
public class ExceptionTest {
public static void main(String[] args) {
// 检查性异常 (编译阶段发生)
try {
FileInputStream fis = new FileInputStream("d:\\nba.txt");
}catch (FileNotFoundException e) {
e.printStackTrace();
}
System.out.println("程序执行结束了....");
}
}
6.2 异常的抛出 异常向调用者抛出
import java.io.FileInputStream;
import java.io.FileNotFoundException;
public class ExceptionTest {
public static void main(String[] args) throws FileNotFoundException { // throws用于异常的抛出
// 检查性异常 (编译阶段发生),不进行处理则程序编译不通过
FileInputStream fis = new FileInputStream("d:\\nba.txt");
System.out.println("程序执行结束了....");
}
}
7、复习:方法重写的原则 案例:重写不能抛出更大的异常
a,要求 方法名相同、参数列表相同、返回值类型相同也相同;
b,访问权限不能变小,可以相同 或者 变大;
c, 不能抛出更大的异常类型。
总结,子类中重写之后的方法:
可以抛出与父类中相同的异常,可以抛出子类异常、或者不抛出异常;
但是不能抛出 更大的异常 ,或者抛出同级别不一样的异常;
8、检测性异常 和 非检测性异常的比较
案例:
import java.io.FileInputStream; public class ExceptionTest { public static void main(String[] args) { // 非检测性异常(运行阶段发生) int a = 10; int b = 0; System.out.println(a/b); // 检查性异常 (编译阶段发生) FileInputStream fis = new FileInputStream("d:\\nba.txt"); // 程序编译不通过 System.out.println("程序执行结束了...."); } }
9、Finally 语句块
public class FinallyTest {
public static void main(String[] args) {
int a = 10;
int b = 0;
try {
System.out.println(a/b);
} catch (ArithmeticException e) {
e.printStackTrace();
}finally {
System.out.println("无论是否发生异常都必然会执行这里的代码!!!");
}
System.out.println("程序正常结束了...");
}
}
10、自定义异常 案例:自定义异常
1、为何需要自定义异常?
在Java语言中即便提供了大量的异常类型供开发者使用,但是不可能每一种类型都恰好满足用户的针对性需求。
如:没有一种可以对学号不合理的针对性异常类。
为了专门表达学号不合理的异常,此时就需要自定义异常!
2、 自定义异常的方式步骤?
a、自定义异常类 继承Exception类 或者 是 Exception类的其他子类;
b、 提供一个无参的 构造方法;
c、 再提供一个字符串类型 作为 形参的有参构造方法即可;
注意:
自定义异常类的命名规范: 使用Exception结尾; 【阿里巴巴开发手册】