异常机制其实是帮助找到程序中出现的问题
-
-
throw new 异常类名(参数) // 给调用者抛出一个空指针异常 throw new NullPointerException("要访问的arr数组不存在,值为null"); // 给调用者抛出一个索引越界异常 throw new IndexOutOfBoundsException("该索引超出了引用的范围");
将问题标识出来,报告给调用者,如果方法内通过throw抛出了一个编译期异常,又没有通过捕获处理(try..catch),那么必须通过throws进行声明,让调用者去处理。
关键字throws运用在方法的声明上,用于表示不处理异常,提醒调用者该方法的调用携带的是有异常信息,谁调用谁处理。
修饰符 返回值类型 方法名(参数列表) throws 异常类名1,异常类名2,....{}
public class DemoThrows {
public static void main(String[] args) {
read("C:/a.txt");
}
public static void read(String path) throws FileNotFoundException{
// 校验 如果你传递的路径不是以.txt的结尾的,抛出调用者文件找不到异常
if (!path.endsWith(".txt")) {
// 抛出一个文件找不到异常
throw new FileNotFoundException("文件找不到");
}
}
}
捕获异常 try...catch
如果异常出现的话,会立刻终止程序。
-
如果使用throws关键字来声明式处理,由该方法的调用者来处理(很危险)
-
在方法中使用try...catch的语句块来处理异常
try {
// 编写的可能会出现的异常代码
//.....
} catch (异常类型 e) {
// 处理异常的逻辑代码
// 记录日志 // 打印异常信息 // 继续往上抛
}
try:该语句块中可能出现异常的代码
catch:用来进行某种异常的捕获,实现对捕获到的异常进行处理。
备注:try和catch都不能单独使用,一般建议连用。
try {
//
} catch (异常类型 e) {
// ....
}
.....
finally {
//....
}
备注:中间的catch语句块可以省略,finally不能单独使用,建议连用。
1. 如果finally语句块中有return语句,永远返回的是finally语句块中的结果值
2. 当只有在try或者catch中调用退出JVM的相关方法,此时finally才不会被执行到,否则finally永远会执行。
什么是自定义异常类?
例如:我想自定义一个业务逻辑异常类:注册异常 RegisterException。
异常类如何定义?
-
自定义一个编译期异常,自定义类继承于
java.lang.Exception
。 -
自定义一个运行期异常类,自定义类 继承于
java.lang.RuntimeException
。
自定义异常例子
// 首先 定义一个注册异常类 RegisterException --->业务逻辑异常类
public class RegisterException extends RuntimeException {
// 空参构造
public RegisterException(){}
// 有参构造
public RegisterException(String message) {
super(message);
}
}
public class Demo {
// 使用数组模拟数据库 已存在多个账户名称
public static String[] names = {"白菜","萝卜","哒哒哒"};
public static void main(String[] args) {
// Scanner
Scanner scan = new Scanner(System.in);
String name = scan.next();
// 校验账户是否已被注册过
try {
// 可能会引发异常的代码
checkName(name);// 如果没有发生异常,就代表注册成功
System.out.println("注册成功!")
names = Arrays.copyOf(names,names.length+1);
names[names.length-1] = name;
} catch (RegisterException e) {
// 异常的处理逻辑
e.printStackTrace();
}
}
// 校验账户是否已被注册
public static boolean checkName(String usernmae) throws RegisterException {
for (String name : names) {
if (name.equals(username)) {
// 表明 名字已经注册过了,就抛出注册异常
throw new RegisterException("亲,您的名字已经被注册了,再换个名字吧!");
}
}
return true;
}
}