【自学笔记】 Java基础 - 异常
# 异常## 概述
就是程序出现了不正常的情况,程序执过程中,出现的非正常的情况,最终会导致JVM的非正常停止。
注意:语法错误不算在异常体系中
## 异常体系
### Throwable
#### Error
工程师不能处理,只能尽量避免
#### Exception
编译期异常,进行编译(写代码)java程序出现的问题,由于使用不当,可以避免的RuntimeException:运行期异常,java程序运行过程中出现的问题
- RunTimeException及其子类:运行时异常。(通常是值空指针,数组索引越界异常 )
- 除RunTimeException之外的所有异常:编译器必须处理,否则程序不能通过编译
注:
- Javac.exe 编译时异常,是在编译成class文件时必须要处理的异常,也称之为受检异常
- java.exe 运行时异常,在编译成class文件不需要处理,在运行字节码时可能出现的异常。也称之为非受检异常
## 处理异常的方法:
- public String getMessage()`:获取异常的描述信息,原因(提示给用户的时候,就提示错误原因。
- public String toString()`:获取异常的类型和异常描述信息(不用)。
- public void printStackTrace()`:打印异常的跟踪栈信息并输出到控制台。(字体是红色字体)
## 虚拟机异常处理
当代码当中出现了异常,在异常报错的地方虚拟机会去创建一个异常对象, new XXX()异常对象,虚拟机会查看程序中有没有处理异常的代码,如果没有,就交给本方法的使用者处理,最终会交给虚拟机处理。
注:
虚拟机会终止异常之后的代码运行
## 异常处理
### throw
#### 作用
在指定的方法中抛出指定的异常
#### 格式
throw new xxxException("异常产生的原因");
#### 注意事项
1.throw关键字,必须写在方法的内部
2.throw关键字后边new的对象必须是Exception或者Exception的子类对象
3.throw关键字抛出指定的异常对象,我们就必须处理这个异常对象
4.throw关键字后边创建的是RuntimeException或者RuntimeExcept的子类,我们可以不处理默认交给JVM处理(打印异常对象,中断程序)
5.throw关键字后边创建的是编译异常(写代码的时候报错),我们就必须处理这个异常,要么throws,要么try...catch
```Java
public class Throw{
public static void main(String[] args) {
int[] arr = null;
int e = getElement(arr,1);
System.out.println(e);
}
/*
定义一个方法,获取数组指定索引处的元素
参数:
int[] arr
int index
以后(工作中)我们首先必须对方法传递过来的参数进行合法性校验
如果参数不合法,那么我们就必须使用抛出异常的方法,告知方法的调用者,传递的参数有问题
注意:
NullPointerException是一个运行期异常,我们不用处理,默认交给JVM处理
*/
public static int getElement(int[] arr,int index) {
/*
我们可以对传递过来的参数数组,进行合法性校验
如果数组arr的值是null
那么我们就抛出空指针异常,告知方法的调用者"传递的数组的值是null"
*/
if (arr == null){
throw new NullPointerException("传递的数组值是Null");
}
/*
对index进行校验
如果index的范围不在数组的索引范围内
抛出数组索引越界异常,告知方法的调用者"传递的索引超出了数组的使用范围"
*/
if(index < 0 || index > arr.length-1){
throw new ArrayIndexOutOfBoundsException("传递的索引超出了数组的使用范围");
}
int ele = arr;
return ele;
}
}
```
### throws
处理异常的第一种方式
#### 作用:
当方法的内部抛出异常对象的时候,那么我们就必须处理这个异常对象
可以使用throws关键字处理异常对象,会把异常对象声明抛出给方法的调用者处理(自己不处理,给别人处理)最终交给JVM处理-->中断处理
#### 使用格式:
```Java
修饰符 返回值类型 方法名(参数列表) throws AAAException .... {
throw new AAAException("产生原因");
...
}
````
#### 注意事项
1.throws关键字必须写在方法声明处
2.throws关键字后边声明的异常必须是Exception或者是Exception的子类
3.方法内部如果抛出了多个异常对象,那么throws后边必须也声明多个异常如果抛出的多个异常对象有子父类关系,那么直接声明父类异常即可、
4.调用了一个声明抛出异常的方法,我们就必须处理声明的异常,要么继续使用throws声明抛出,交给方法的调用者处理,最终交给JVM处理要么try...catch自己处理异常
5.如果声明的时一个运行时异常,那么声明的时候可以省略
```Java
public class Throws {
public static void main(String[] args) throws IOException{
readFile("C:\\a.txt");
}
/*
定义一个方法,对传递的文件路径进行合法性处理
如果路径不是"c:\\a.txt",那么我们就抛出文件找不到异常对象,告知方法的调用者
注意:
FileNotFoundException是编译异常,抛出了编译异常,就必须处理这个异常
可以使用throws继续声明抛出FileNotFoundException这个异常对象,让方法的调用者处理
*/
public static void readFile(String fileName) throws IOException{
if (!fileName.equals("C:\\a.txt")){
throw new FileNotFoundException("传递的文件路径不是C:\\a.txt");
}
/*
判断传递的路径是不是.txt结尾
如果不是抛出IO异常对象,告知方法的调用者,文件名的后缀不对
*/
if (!fileName.endsWith(".txt")){
throw new IOException("文件的后缀名不对");
}
System.out.println("读取文件");
}
}
```
### try...catch
#### 格式
```Java
try{
可能产生异常的代码
}catch(定义一个异常的变量,用来接收try中抛出的异常对象){
异常的处理逻辑,产生异常对象之后,怎么处理对象
一般在工作中,会把异常的信息记录到一个日志中
}
...
catch(异常类名 变量名){
处理逻辑
}
```
### 注意事项
1.try中可能抛出多个异常对象,那么就可以使用多个catch来处理这些异常对象
2.如果try中产生了异常,那么就会执行catch中的异常处理逻辑,执行完毕catch中的处理逻辑,继续执行try...catch之后的代码,如果try中没有产生异常,那么就不会执行catch中异常的处理逻辑,执行完try中的代码,继续执行try...catch之后的代码
3.如果抛出的问题没用被处理,那么就会抛给JVM执行
```Java
public class TryCatch {
public static void main(String[] args) {
try {
readFile("d:\\a.tx");
}catch (IOException e){ //try中抛出什么异常对象,catch就定义什么异常变量,用来接收这个异常对象
System.out.println("传递的文件后缀不是.txt");
}
System.out.println("后续代码");
}
/*
判断传递的路径是不是.txt结尾
如果不是抛出IO异常对象,告知方法的调用者,文件名的后缀不对
*/
public static void readFile(String fileName) throws IOException{
if (!fileName.endsWith(".txt")){
throw new IOException("文件的后缀名不对");
}
}
}
```
### finally代码块
```Java
try{
可能产生异常的代码
}catch(定义一个异常的变量,用来接收try中抛出的异常对象){
异常的处理逻辑,产生异常对象之后,怎么处理对象
一般在工作中,会把异常的信息记录到一个日志中
}
...
catch(异常类名 变量名){
处理逻辑
}finally{
无论是否出现异常,都会执行
}
```
#### 注意事项:
1.不能单独使用,必须配合try一起使用
2.finally一般用于资源释放,无论程序是否出现异常,最后都要资源释放
3.如果finally有return语句,永远就会返回finally中的结果,避免该情况
### 自定义异常
java提供的异常类,不够用,需要自己定义一些异常类
#### 格式:
```Java
public class XXXException extends Exception | RuntimeException{
添加一个空参数的构造方法
添加一个带异常信息的构造方法,其中调用super(xxx),把传进来的参数传给父类构造方法
}
```
#### 注意事项
1.自定义异常类一般都是以Exception结尾,说明该类是一个异常类
2.自定义异常类,必须的继承Exception或者RuntimeException
3.继承:Exception:那么自定义的异常类就是一个编译期异常,如果方法内部抛出了编译期异常就必须处理这个异常,要么throws,要么try...catch
4.继承:RuntimeException:那么自定义的异常类,就是一个运行期异常,无需处理,交给虚拟机处理(中断处理)
页:
[1]