什么是异常?
Java程序在运行时出现的问题就叫异常
jdk中将异常一新封装成了一个个的类,当出现问题时,就会创建异常对象,抛出异常信息(问题原因、位置)
1.异常
1.1的继承体系
Throwable 是所有错误(error)和异常(Exception)的父类
错误(error)是程序运行过程中出现的严重问题(内存不够),只能修改代码避免这种错误
Exception 是Throwable 的子类,用来表示java程序中可能出现的异常,并要求对异常进行合理的处理
RuntimeException 和CheckedExceptions 两个是Exception的子类
RuntimeException及其子类 (运行时异常) java运行过程中出现的异常
CheckedExceptions 编译时异常
1.2异常和错误的区别
异常:是指程序在编译、运行期间发生了某种异常,可以对异常进行具体的处理,如果不处理异常,程序会结束
错误:是指程序运行时发生了某种错误,Error错误通常没有具体的处理方法,一般情况下错误都发生在JVM,我们无法处理
1.3 异常处理
1.jvm默认处理方式
一旦发生异常,产生异常代码的下面的代码就不再执行
public class Test {
public static void main(String[] args) {
// 5.jvm 接收到异常后,按默认处理方法处理
// int[] arr=new int[1000*1000*1024];
// System.out.println(arr[0]);
int [] arr=new int[3];
int j=method(arr); //3.main方法接收到方法跑过来的异常对象
//4.jvm 当前main方法有没有处理这个异常的代码,
//如果没有,继续抛给main方法的调用者,这里指的是jvm
System.out.println(j);
}
public static int method(int[] arr){
int i=arr[3]; //1.当程序运行到arr[3]时,jvm检查有没有索引3,
// 没有jvm会自动抛出一个异常.ArrayIndexOutOfBoundsException
//2.检查method方法有没有处理这个异常的代码,
// 没有找到,继续把这个异常抛给method的调用者
return i;
}
}
```
1.4编译时异常和运行时异常
运行时异常:RuntimeException及其子类
IndexOutOfBoundsException
NullPointerException 空指针异常
ClassCastException 类型转换异常
编译时异常:
非RuntimeException及其子类的异常。就在编译阶段会出现的异常
ClassNotFoundException
FileNotFoundException
编译时异常必须处理
1.5 处理异常
捕获:java对异常有针对性额语句进行捕获,对出现的异常进行指定方式处理
格式:
try{
//可能出现异常的代码
}catch(异常类 变量){
//遗产处理语句
}
int i=10;
int j=0;
int [] arr=null;
try {
j=arr[3];
int s = i / j;
}catch (ArithmeticException e){
System.out.println("算术异常");
e.printStackTrace();
}catch (NullPointerException e){
System.out.println("空指针异常");
}catch (Exception e){
System.out.println("异常");
}
多个catch的异常不能相同,如果异常存在子类父类关系,子类在上面,父类在下面
1.5.1 finally代码块
无论try是否发生异常,finally语句一定会执行
格式:
try{
//可能出现异常的代码
}catch(异常类 变量){
//遗产处理语句
}finally{
//无论try是否发生异常,finally语句一定会执行
一般finally里面里释放资源(io,数据库连接)的代码块
}
1.6 抛出异常 throw
在java中,提供这个throw关键字,用力抛出一个指定的异常对象。
1.创建一个异常对象
2.将这个异常对象告诉调用者:throw 异常对象
public static void main(String[] args) { //5.jvm 接收到异常后,按默认处理方法处理
// int[] arr=new int[1000*1000*1024];
// System.out.println(arr[0]);
//int [] arr=new int[3];
int[] arr=null;
int j=method(arr,3); //3.main方法接收到方法跑过来的异常对象
//4.jvm 当前main方法有没有处理这个异常的代码,
//如果没有,继续抛给main方法的调用者,这里指的是jvm
System.out.println(j);
}
public static int method(int[] arr,int i){
if(arr==null){
throw new NullPointerException();
}
if(i>=arr.length){
// return -1;
throw new ArrayIndexOutOfBoundsException();
}
if(i<0){
throw new ArrayIndexOutOfBoundsException();
}
int j=arr[i]; //1.当程序运行到arr[3]时,jvm检查有没有索引3,
// 没有jvm会自动抛出一个异常.ArrayIndexOutOfBoundsException
//2.检查method方法有没有处理这个异常的代码,
// 没有找到,继续把这个异常抛给method的调用者
return j;
}
1.7 声明异常 throws
public static int method(int[] arr,int i) throws NullPointerException,ArrayIndexOutOfBoundsException
如果在方法内部抛出编译时异常,没有捕获,方法上必须使用throws 声明,让调用者处理
1.8 异常常见方法
printStackTrace的堆栈跟踪功能显示出程序运行到当前类的执行流程
/**
* Returns the detail message string of this throwable.
* @return the detail message string of this {@code Throwable} instance
* (which may be {@code null}).
*/
public String getMessage() {
return detailMessage;
}
//返回该异常的详细信息
public void printStackTrace() {
printStackTrace(System.err);
}
//在控制台输出该异常的的名字和信息、以及出现的位置
2.自定义异常
自定义的异常用法通常包含四步:
1.定义异常类 2.写继承关系 3.空参构造 4.代参构造
如下:我自定义了一个异常类NameFormatException,用来在用户年龄错误时抛出
public class NameFormatException extends RuntimeException{
public NameFormatException() {
}
public NameFormatException(String cause) {
super(cause);
}
}
public class Student {
private String name;
private int age;
public Student() {
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
//判断年龄是否符合
if(name.length()<3&&name.length()>10){
throw new NameFormatException(name+"ss");
}
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
if(age<18&&age>30){
throw new RuntimeException();
}
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
注:文章来自闫军锋老师课堂笔记扩充修改