异常笔记
https://www.runoob.com/java/java-exceptions.html?tdsourcetag=s_pcqq_aiomsg
异常概念
异常体系、分类、异常与错误的区别
Throwable是Java中所有错误与异常的父类
异常的产生过程解析
使用throw关键字抛出异常
运行期异常RuntimeException以及其子类 直接throw new xxxException抛出异常,默认交给Java虚拟机处理异常
空指针异常、数组索引越界是运行期异常的子类,所以直接抛出给虚拟机处理
使用Objects类中的静态方法requireNoneNull()判断引用对象是否为空,如果是抛出异常,可以减少代码量。
异常的处理
方法一:throws
readFile方法将异常抛给其调用者即main方法,然后main方法再将异常抛给JVM
同时有两个异常,其中FileNotFoundException是IOException的子类,所以在main方法抛出异常时只用抛出IOException就可,同时这两个异常又都是Exception的子类,所以在main方法抛出异常时只用抛出Exception也可。
下面的编译报错,在抛出异常对象后要对其进行处理,在readFile方法throws后面加上IOException抛出异常
方法二: try……catch
如果一直使用throws关键字,最后异常会被交给JVM处理,而虚拟机采用的是中断处理,那么后面的代码就无法执行,使用try……catch格式,异常就会被catch到,交给在catch(Exception e)中会被定义的异常对象接收处理。
Throwable处理异常的三个方法
其中直接打印e默认的就是e.toString(),直接打印引用类型的对象,因为Exception中重写了toString方法,打印异常的详细内容
finally关键字
在try中出现异常的语句后面的语句无法执行 直接跳到catch中
package ExceptionTest;
import java.io.IOException;
public class FinallyTest {
public static void main(String[] args) {
try {
readFile("a.xt");
System.out.println("异常语句后的代码");
} catch (IOException e) {
System.out.println(e);
}finally {
System.out.println("资源释放");
}
System.out.println("后续代码");
}
private static void readFile(String fileName) throws IOException{
if(!fileName.endsWith(".txt")){
throw new IOException("文件名不是以.txt结尾");
}else{
System.out.println("文件名正确");
}
}
}
出现异常语句的后面的代码直接跳转无法执行所以使用finally关键字,不管是否异常finally代码块中的语句都能执行
多个异常捕获
分别处理
一次捕获多次处理
一次捕获,一次处理,直接使用父类对象,多态
Exception e = new IndexOutOfBoundsException;
父类 子类
注意事项:finally代码块中有return语句
如果finally有return语句,永远返回finally中的结果,避免该情况,不要在finally代码块中使用return语句
注意事项:子父类异常
自定义异常类
RegisterException 自定义异常类中有两个构造方法,直接调用父类的方法体
自定义异常类练习使用
自定义的异常类RegisterException
package ExceptionTest;
public class RegisterException extends Exception{ // 也可以继承RuntimeException
public RegisterException() {
}
public RegisterException(String message) {
super(message);
}
}
使用
throws
package ExceptionTest;
import java.util.Scanner;
public class DemoMain {
static String[] username = {"库里","艾佛森","汤普森"};
public static void main(String[] args) throws RegisterException{
Scanner sc = new Scanner(System.in);
String name = sc.next();
check(name);
}
public static void check(String name) throws RegisterException{
for (String s : username) {
if(name.equals(s)){
throw new RegisterException("亲,该用户名已注册");
}
}
System.out.println("注册成功");
}
}
try……catch
package ExceptionTest;
import java.util.Scanner;
public class DemoMain {
static String[] username = {"库里","艾佛森","汤普森"};
public static void main(String[] args) /*throws RegisterException*/{
Scanner sc = new Scanner(System.in);
String name = sc.next();
check(name);
}
public static void check(String name) /*throws RegisterException*/{
for (String s : username) {
if(name.equals(s)){
try {
throw new RegisterException("亲,该用户名已注册");
} catch (RegisterException e) {
System.out.println(e);
return;//否则会继续执行后续代码 打印注册成功
}
}
}
System.out.println("注册成功");
}
}
混合使用
package ExceptionTest;
import java.util.Scanner;
public class DemoMain {
static String[] username = {"库里","艾佛森","汤普森"};
public static void main(String[] args) /*throws RegisterException*/{
Scanner sc = new Scanner(System.in);
String name = sc.next();
try {
check(name);
} catch (RegisterException e) {
System.out.println(e);
}
}
public static void check(String name) throws RegisterException /*throws RegisterException*/{
for (String s : username) {
if(name.equals(s)){
throw new RegisterException("亲,该用户名已注册");
}
}
System.out.println("注册成功");
}
}