1、异常的注意事项
多个异常的使用捕获又该如何处理呢?
1、多个异常分别处理。
public static void main(String[] args) {
//1、多个异常分别处理。
try{
int[] arr = {1, 2, 3};
System.out.println(arr[3]);
}catch(ArrayIndexOutOfBoundsException e){
System.out.println(e);
}
try{
int[] arr2 = {4,5,6};
System.out.println(arr2[5]);
}catch (ArrayIndexOutOfBoundsException e){
System.out.println(e);
}
//运行时异常被抛出可以不处理,既不捕获也不声明抛出
//默认给虚拟机处理,终止程序,什么时候不抛出运行时异常了,在未来继续执行
int[] arr = {1, 2, 3};
System.out.println(arr[3]);
int[] arr2 = {4,5,6};
System.out.println(arr2[5]);
System.out.println("后续代码!");
}
2、多个异常一次捕获,多次处理。
一个try多个catch注意事项:
catch里面定义的异常变量,如果有子父类关系,那么子类的异常变量必须写在上面,否则会报错。
public static void main(String[] args) {
//2、多个异常一次捕获,多次处理。
try{
int[] arr = {1, 2, 3};
// System.out.println(arr[3]);
int[] arr2 = {4,5,6};
System.out.println(arr2[5]);
}catch(ArrayIndexOutOfBoundsException e){
System.out.println(e);
}catch (Exception e){
System.out.println(e);
}
int[] arr = {1, 2, 3};
System.out.println(arr[3]);
int[] arr2 = {4,5,6};
System.out.println(arr2[5]);
System.out.println("后续代码!");
}
3、多个异常一次捕获一次处理。
public static void main(String[] args) {
//3、多个异常一次捕获一次处理。
try{
int[] arr = {1, 2, 3};
System.out.println(arr[3]);
int[] arr2 = {4,5,6};
System.out.println(arr2[5]);
}catch(ArrayIndexOutOfBoundsException e){
System.out.println(e);
}
int[] arr = {1, 2, 3};
System.out.println(arr[3]);
int[] arr2 = {4,5,6};
System.out.println(arr2[5]);
System.out.println("后续代码!");
}
2、finally注意事项
如果finally有return语句,永远返回finally中的结果,避免该情况。
public class Demo02Exception {
public static void main(String[] args) {
int a = getA();
System.out.println(a);
}
//定义一个方法,返回变量a的值
public static int getA(){
int a = 10;
try{
return a;
}catch (Exception e){
System.out.println(e);
}finally {
//一定会执行的代码
a = 100;
return a;
}
}
3、子父类的异常:
如果父类抛出了多个异常,子类重写父类方法时,抛出和父类相同的异常或者是父类异常的子类或者不抛出异常。
父类方法没有抛出异常,子类重写父类该方法时也不可抛出异常,此时子类产生异常,只能捕获处理,不能声明抛出。
注意:
父类异常什么样,子类异常就什么样。
public class Fu {
public void show01() throws NullPointerException,ClassCastException{}
public void show02() throws IndexOutOfBoundsException{}
public void show03() throws IndexOutOfBoundsException{}
public void show04() throws Exception {}
}
class Zi extends Fu{
//子类重写父类方法时,抛出和父类相同的异常
public void show01() throws NullPointerException,ClassCastException{}
//子类重写父类方法时,抛出父类异常的子类
public void show02() throws ArrayIndexOutOfBoundsException{}
//子类重写父类方法时,不抛出异常
public void show03() {}
//父类方法没有抛出异常,子类重写父类方法时也不能抛出异常
// public void show04() {}
//此时子类产生异常,只能捕获处理,不能声明抛出
public void show04() {
try {
throw new Exception("编译器异常");
} catch (Exception e) {
e.printStackTrace();
}
}
4、自定义异常类
自定义异常类:
java提供的异常类,不够我们使用,需要自己定义一些异常类
格式:
public class XXXException extends Exception / RuntimeException{
添加一个空参数的构造方法
添加一个带异常信息的构造方法
}
注意:
1、自定义异常类一般都是以Exception结尾,说明该类是一个异常类
2、自定义异常类,必须得继承Exception或者RuntimeException
继承Exception:那么自定义的异常就是一个编译期异常,如果方法内部抛出了编译期异常,就必须处理这个异常,要么throws,要么try…catch
继承RuntimeException: 那么自定义的异常类就是一个运行期异常,无需处理,交给虚拟机处理(中断处理)
public class RegisterException extends /*Exception*/ RuntimeException{
//添加一个空参数的构造方法
public RegisterException(){
}
/*
添加一个带异常信息的构造方法
查看源码发现,所有的异常类都有一个带异常信息的构造方法,方法内部会调用父类带异常信息的方法,让父类来处理这个异常信息
*/
public RegisterException(String message){
super(message);
}
}
eg:模拟注册操作
要求:我们模拟注册操作,如果用户名已存在,则抛出异常并提示:亲,该用户名已被注册!
分析:
1、使用数组保存已注册过的用户名(数据库)
2、使用Scanner获取用户输入的注册的用户名(前端、页面)
3、定义一个方法,对用户输入的注册的用户名进行判断
遍历存储已经注册过用户名的数组,获取每一个用户名
使用获取到的用户名和用户名输入的用户名进行比较
true:
用户名已存在,抛出RegisterException异常,告知用户用户名已被注册
false:
继续遍历比较
如果循环结束了,还没有找到重复的,提示用户:“恭喜您,注册成功!”
public class Demo01RegisterException {
//1、使用数组保存已注册过的用户名(数据库)
static String[] usernames = {"张三","张三","王五"};
public static void main(String[] args) /*throws RegisterException*/ {
// 2、使用Scanner获取用户输入的注册的用户名(前端、页面)
Scanner sc = new Scanner(System.in);
System.out.print("请输入您要注册的用户名:");
String username = sc.next();
checkUsernames(username);
}
// 3、定义一个方法,对用户输入的注册的用户名进行判断
public static void checkUsernames(String username) /*throws RegisterException*/ {
//遍历存储已经注册过用户名的数组,获取每一个用户名
for (String name : usernames) {
// 使用获取到的用户名和用户名输入的用户名进行比较
if(name.equals(username)){
//true:用户名已存在,抛出RegisterException异常,告知用户用户名已被注册
try {
throw new RegisterException("亲,该用户已被注册!");
} catch (RegisterException e) {
e.printStackTrace();
return;//结束方法
}
}
}
//如果循环结束了,还没有找到重复的,提示用户:“恭喜您,注册成功!”
System.out.println("恭喜您,注册成功!");
}
}
public static void checkUsernames(String username) /*throws RegisterException*/ {
//遍历存储已经注册过用户名的数组,获取每一个用户名
for (String name : usernames) {
// 使用获取到的用户名和用户名输入的用户名进行比较
if(name.equals(username)){
//true:用户名已存在,抛出RegisterException异常,告知用户用户名已被注册
throw new RegisterException("亲,该用户名已被注册了!");//抛出运行期异常,无需处理,交给JVM处理,中断处理
}
}
//如果循环结束了,还没有找到重复的,提示用户:“恭喜您,注册成功!”
System.out.println("恭喜您,注册成功!");
}