一、异常的灵魂四问
1、一问
- 如果try中没有遇到问题,怎么执行?
package com.app.demo35_Exception_test;
public class Test1 {
public static void main(String[] args) {
/*
异常的灵魂四问
一问:如果try中没有遇到问题,怎么执行?
答:如果try中没有遇到问题,会将try中的所有代码都执行完,但不执行catch中的代码
*/
int[] arr = {1, 3, 4, 2, 6};
try {
System.out.println(arr[0]);
}catch (ArrayIndexOutOfBoundsException e) {
System.out.println("索引越界了~");
}
System.out.println("看我执行了吗?");
}
}
1
看我执行了吗?
Process finished with exit code 0
2、二问
- 如果try中可能会遇到多个问题,怎么执行?
package com.app.demo35_Exception_test;
public class Test2 {
public static void main(String[] args) {
/*
异常的灵魂四问
二问:如果try中可能会遇到多个问题,怎么执行?
答:如果try中遇到多个问题,要写多个catch与之对应
细节:如果我们要捕获多个异常,这些异常中如果存在父子关系的话,那么父类一定要写在下面
了解性:在JDK7之后,我们可以在catch中同时捕获多个异常,中间用 | 进行隔开
表示如果出现了A异常或B异常的话,采取同一种处理方案
*/
int[] arr = {1, 3, 4, 2, 6};
/*try {
System.out.println(arr[7]); // 异常:ArrayIndexOutOfBoundsException
System.out.println(2/0); // 异常:ArithmeticException
}catch (ArrayIndexOutOfBoundsException e) {
System.out.println("索引越界了~");
}catch (ArithmeticException e) {
System.out.println("除数不能为0");
}catch (Exception e) {
System.out.println("Exception");
}*/
// JDK7之后
try {
System.out.println(arr[7]); // 异常:ArrayIndexOutOfBoundsException
System.out.println(2/0); // 异常:ArithmeticException
}catch (ArrayIndexOutOfBoundsException | ArithmeticException e) {
System.out.println("索引越界了~");
}catch (Exception e) {
System.out.println("Exception");
}
System.out.println("看我执行了吗?");
}
}
索引越界了~
看我执行了吗?
Process finished with exit code 0
3、三问
- 如果try中遇到的问题没有被捕获,怎么执行?
package com.app.demo35_Exception_test;
public class Test3 {
public static void main(String[] args) {
/*
异常的灵魂四问
三问:如果try中遇到的问题没有被捕获,怎么执行?
答:会将问题交给虚拟机进行处理,虚拟机就会采用默认异常处理方式(将异常以红色字体打印在控制台并结束程序的执行)。
*/
int[] arr = {1, 3, 4, 2, 6};
try {
System.out.println(arr[10]); // ArrayIndexOutOfBoundsException
}catch (ArithmeticException e) {
System.out.println("除数不能为0~");
}
System.out.println("看我执行了吗?");
}
}
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 10
at com.app.demo35_Exception_test.Test3.main(Test3.java:13)
Process finished with exit code 1
4、四问
- 如果try中遇到了问题,那么try下面的其他代码还会执行吗?
package com.app.demo35_Exception_test;
public class Test4 {
public static void main(String[] args) {
/*
异常的灵魂四问
四问:如果try中遇到了问题,那么try下面的其他代码还会执行吗?
答:try下面的其他代码将不会执行了,直接跳转到对应的catch当中,执行catch里面的语句体
但是如果没有对应catch与之匹配,那么还是会交给虚拟机进行处理。
*/
int[] arr = {1, 3, 4, 2, 6};
try {
System.out.println(arr[10]); // ArrayIndexOutOfBoundsException
System.out.println("看看我执行了吗? ...try下面的其他代码");
}catch (ArrayIndexOutOfBoundsException e) {
System.out.println("索引越界了~");
}
System.out.println("看看我执行了吗?...其他代码");
}
}
索引越界了~
看看我执行了吗?...其他代码
Process finished with exit code 0
总结
灵魂一问:如果try中没有遇到问题,怎么执行?
答:会将try中所有的代码全部执行完毕,不会执行catch里面的代码。
灵魂二问:如果try中可能会遇到多个问题,怎么执行?
答:会写多个catch与之对应,父类异常需要写在下面。
灵魂三问:如果try中遇到的问题没有被捕获,怎么执行?
答:相当于try…catch白写了,当前异常会交给虚拟机处理。
灵魂四问:如果try中遇到了问题,那么try下面的其他代码还会执行吗?
答:不会执行了。try中遇到问题,直接跳转到对应的catch。
如果没有对应的catch与之匹配,则交给虚拟机处理。
二、异常综合练习
- 很多时候,我们都不知道到底何时该抛出异常,何时该捕获异常?
- 其实,抛出用得最多的是在写方法的时候,抛出异常,告诉调用者出错了!
- 然后,捕获用得最多的是在调用方法的时候,捕获异常,不能让程序停止运行!
1、需求
- 键盘录入自己心仪的女朋友的姓名和年龄。
- 姓名的长度在3-10之间,年龄范围为18-40岁
- 超出以上范围是异常数据不能赋值,需要重新录入,一直录到正确为止。
提示:
- 需要考虑用户在键盘录入时的所有情况。
- 比如:录入年龄时超出范围,录入年龄时录入了abc等情况。
自定义异常类
package com.app.demo35_Exception_test.test;
/*
自定义运行时异常:姓名长度超出范围异常
1.继承RuntimeException
2.重写构造器
*/
public class NameLengthOutOfRangeRuntimeException extends RuntimeException{
public NameLengthOutOfRangeRuntimeException() {
}
public NameLengthOutOfRangeRuntimeException(String message) {
super(message);
}
}
package com.app.demo35_Exception_test.test;
/*
自定义编译时异常:年龄超出范围异常
1.继承Exception
2.重写构造器
*/
public class AgeOutOfRangeException extends Exception {
public AgeOutOfRangeException() {
}
public AgeOutOfRangeException(String message) {
super(message);
}
}
女朋友类
package com.app.demo35_Exception_test.test;
/*
女朋友类
*/
public class GirlFriend {
private String name;
private int age;
public GirlFriend() {
}
public GirlFriend(String name, int age) {
this.name = name;
this.age = age;
}
/**
* 获取
* @return name
*/
public String getName() {
return name;
}
/**
* 设置
* @param name
*/
public void setName(String name) {
// 判断姓名长度是否超出规定范围
int len = name.length();
if (len < 3 || len > 10) {
// 如果超出范围,则创建姓名长度超出范围运行时异常对象,并抛出
throw new NameLengthOutOfRangeRuntimeException();
}
// 如果在规定范围内,则赋值
this.name = name;
}
/**
* 获取
* @return age
*/
public int getAge() {
return age;
}
/**
* 设置
* @param age
*/
public void setAge(int age) throws AgeOutOfRangeException {
// 判断年龄是否超出规定范围
if (age < 18 || age > 40) {
// 如果超出范围,则创建年龄超出范围编译时异常对象,并抛出
throw new AgeOutOfRangeException();
}
// 如果在规定范围内,则赋值
this.age = age;
}
public String toString() {
return "GirlFriend{name = " + name + ", age = " + age + "}";
}
}
测试类
package com.app.demo35_Exception_test.test;
import java.util.Scanner;
public class Test {
public static void main(String[] args) {
/*
异常综合练习:
需求:
- 键盘录入自己心仪的女朋友的姓名和年龄。
- 姓名的长度在3-10之间,年龄范围为18-40岁
- 超出以上范围是异常数据不能赋值,需要重新录入,一直录到正确为止。
提示:
- 需要考虑用户在键盘录入时的所有情况。
- 比如:录入年龄时超出范围,录入年龄时录入了abc等情况。
*/
// 1.创建键盘录入对象
Scanner sc = new Scanner(System.in);
// 2.创建女朋友对象
GirlFriend gf = new GirlFriend();
// 3.接收女朋友的信息并封装成女朋友对象
while (true) {
try {
System.out.println("请您输入心仪的女朋友的姓名:");
String name = sc.nextLine();
gf.setName(name); // 封装姓名
System.out.println("请您输入心仪的女朋友的年龄:");
String ageStr = sc.nextLine();
int age = Integer.parseInt(ageStr);
gf.setAge(age); // 封装年龄
// 所有数据都正确录入之后,跳出死循环
break;
} catch (NameLengthOutOfRangeRuntimeException e) {
System.out.println("您输入的姓名长度不在规定范围内~");
} catch (AgeOutOfRangeException e) {
System.out.println("您输入的年龄不在规定范围内~");
} catch (NumberFormatException e) {
System.out.println("您输入的年龄格式有误~ 请输入数字!");
}
}
System.out.println(gf);
}
}
请您输入心仪的女朋友的姓名:
世纪东方恪守妇道肯定是福克斯
您输入的姓名长度不在规定范围内~
请您输入心仪的女朋友的姓名:
小慧慧
请您输入心仪的女朋友的年龄:
17
您输入的年龄不在规定范围内~
请您输入心仪的女朋友的姓名:
小慧慧
请您输入心仪的女朋友的年龄:
asc
您输入的年龄格式有误~ 请输入数字!
请您输入心仪的女朋友的姓名:
小慧慧
请您输入心仪的女朋友的年龄:
29
GirlFriend{name = 小慧慧, age = 29}
Process finished with exit code 0