异常
1.try-catch
1.1 情况 1
情况 1 :使用单个 catch 捕获异常 如果出现的异常和捕获的异常类型匹配 则可以正常捕获
使得程序可以顺利执行完毕 如果出现的异常和捕获的异常类型不匹配 则程序将依然中断
try-catch
try 代码块中存放可能会出现异常的代码
catch 用于捕获异常
try 或者 catch 均不能单独使用
try 必须结合 catch 或者 catch -finally 或者 finally
package com.atguigu.test3;
import java.util.InputMismatchException;
import java.util.Scanner;
/**
* try-catch
* try代码块中存放可能会出现异常的代码
* catch用于捕获异常
*
* try 或者 catch 均不能单独使用
* try 必须结合 catch 或者 catch -finally 或者 finally
*
* 情况1 :使用单个catch捕获异常 如果出现的异常和捕获的异常类型匹配 则可以正常捕获
* 使得程序可以顺利执行完毕 如果出现的异常和捕获的异常类型不匹配 则程序将依然中断
*/
public class TestTryCatch1 {
public static void main(String[] args) {
try{
Scanner in = new Scanner(System.in);
System.out.print("请输入被除数:");
int num1 = in.nextInt();
System.out.print("请输入除数:");
int num2 = in.nextInt();
System.out.println(num1+"/"+ num2 +"="+ num1/ num2);
}catch(InputMismatchException e){
e.printStackTrace(); // 打印异常堆栈信息
}
System.out.println("感谢使用本程序!");
}
}1.2 情况 2
try-catch 情况 2:使用多个 catch 块来捕获异常 按照书写顺序 从前往后匹配 只匹配第一个相符的异常
然后就退出 try-catch 结构
多个 catch 块书写顺序 先写子类 后写 父类
package com.atguigu.test3;
import java.util.InputMismatchException;
import java.util.Scanner;
/**
* try-catch情况2:使用多个catch 块来捕获异常 按照书写顺序 从前往后匹配 只匹配第一个相符的异常
* 然后就退出try-catch结构
*
* 多个catch块书写顺序 先写子类 后写 父类
*
*
*/
public class TestTryCatch2 {
public static void main(String[] args) {
try{
Scanner in = new Scanner(System.in);
System.out.print("请输入被除数:");
int num1 = in.nextInt();
System.out.print("请输入除数:");
int num2 = in.nextInt();
System.out.println(num1+"/"+ num2 +"="+ num1/ num2);
} catch(InputMismatchException e){
System.err.println("出现了输入不匹配异常"); // e.printStackTrace();
} catch(ArithmeticException e){
System.err.println(e.getMessage());
e.printStackTrace();//System.err.println("出现了算数运算异常");//
}catch(Exception e){
e.printStackTrace();
}
System.out.println("感谢使用本程序!");
}
}2.finally
finally 表示不管是否出现异常 以及 异常是否被捕获 都将执行的代码块
finally 不能单独出现 必须结合 try-catch 或者 try
因为 finally 最终都将执行 所以通常用于执行一些关闭资源的操作 比如 关闭流 关闭数据库连接对象等等
finally 不执行的唯一情况:在执行 finally 之前退出 JVM 虚拟机
System.exit(int status) : int 类型的状态码含义:0 表示正常退出 非 0 表示非正常退出
package com.atguigu.test4;
import java.util.InputMismatchException;
import java.util.Scanner;
/**
* finally 表示不管是否出现异常 以及 异常是否被捕获 都将执行的代码块
* finally不能单独出现 必须结合 try-catch 或者 try
* 因为finally最终都将执行 所以通常用于执行一些关闭资源的操作 比如 关闭流 关闭数据库连接对象等等
*
* finally不执行的唯一情况:在执行finally之前退出JVM虚拟机
*
* System.exit(int status) : int类型的状态码含义:0表示正常退出 非0表示非正常退出
*
*/
public class TestFinally {
public static void main(String[] args) {
try{
Scanner in = new Scanner(System.in);
System.out.print("请输入被除数:");
int num1 = in.nextInt();
System.out.print("请输入除数:");
int num2 = in.nextInt();
System.out.println(num1+"/"+ num2 +"="+ num1/ num2);
System.exit(231321);
}catch(InputMismatchException e){
e.printStackTrace(); // 打印异常堆栈信息
}finally{
System.out.println("感谢使用本程序!");
}
}
}3. finally 相关面试题
try 中存在 return 是否还执行 finally ?
执行
try-catch-finally 中 如果 try 中已经 return 了值 那么 finally 中对返回值的操作会不会改变返回值?
如果为基本数据类型 不会改变
如果为引用数据类型 会改变
package com.atguigu.test4;
import java.util.Arrays;
/**
* finally面试题:
* try中存在return 是否还执行finally ?
* 执行
* try-catch-finally中 如果try中已经return了值 那么finally中对返回值的操作会不会改变返回值?
* 如果为基本数据类型 不会改变
* 如果为引用数据类型 会改变
*/
public class TestFinallyInterview {
public static int m1(){
int num = 10;
try{
num++;
return num;
}catch(Exception e){
e.printStackTrace();
}finally{
num++;
}
return num;
}
public static int[] m2(){
int [] nums = {1,2,3,4,5};
try{
return nums;
}catch(Exception e){
e.printStackTrace();
}finally{
for (int i = 0; i < nums.length; i++) {
nums[i]++;
}
}
return nums;
}
public static void main(String[] args) {
int a = m1();
System.out.println(a);
int[] nums = m2();
System.out.println(Arrays.toString(nums));
}
}4.throw 和 throws
throws: 用于在方法声明的位置 参数列表之后 声明当前方法可能会出现哪些异常 可以声明多个异常
多个异常使用逗号分割
方法调用者根据声明的异常类型不同会做出不同的处理
运行时异常(RuntimeException 及其子类):调用者不必处理
检查异常(除了运行时异常以外的其他异常就属于检查异常 CheckedException):调用者必须处理
两种处理方式:
1.使用 try-catch 处理
2.继续在 main 方法上声明 属于声明给 JVM 虚拟机 (其实属于不处理)
throw:用于在方法体内抛出异常 一句只能抛出一个异常
根据抛出的异常类型不同 需要做出不同的处理
如果抛出的为运行时异常 则方法上不必声明
如果抛出的为检查异常 则必须在方法上声明
package com.atguigu.test5;
import java.util.InputMismatchException;
import java.util.Scanner;
/**
*
* throws: 用于在方法声明的位置 参数列表之后 声明当前方法可能会出现哪些异常 可以声明多个异常
* 多个异常使用逗号分割
* 方法调用者根据声明的异常类型不同会做出不同的处理
* 运行时异常(RuntimeException及其子类):调用者不必处理
* 检查异常(除了运行时异常以外的其他异常就属于检查异常CheckedException):调用者必须处理
* 两种处理方式:
* 1.使用try-catch处理
* 2.继续在main方法上声明 属于声明给JVM虚拟机 (其实属于不处理)
*
*
* throw:用于在方法体内抛出异常 一句只能抛出一个异常
* 根据抛出的异常类型不同 需要做出不同的处理
* 如果抛出的为运行时异常 则方法上不必声明
* 如果抛出的为检查异常 则必须在方法上声明
*
*/
public class TestThrowAndThrows {
public static void m1() throws InputMismatchException,ArithmeticException {
}
public static void m2() throws ClassNotFoundException{
}
public static void m3(int age){
if(age < 0 || age > 130){
throw new RuntimeException("年龄不合法");
}
}
public static void m4(int age) throws Exception{
if(age < 0 || age > 130){
throw new Exception("年龄不合法");
}
}
public static void main(String[] args) {
m1();
try {
m2();
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
m3(158);
try {
m4(188);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}5. 自定义异常
当 JDK 提供的异常不能满足开发需求时,我们可以自定义异常
自定义异常步骤:
1.继承异常父类 Throwable 、Exception 、RuntimeException 三者其中之一
2.调用父类中的有参构造完成异常信息的初始化
package com.atguigu.test6;
/**
* 学生类
*/
public class Student {
private String name;
private int age;
private char sex;
public char getSex() {
return sex;
}
public void setSex(char sex) throws InputSexException{
if(sex == '男' || sex == '女'){
this.sex = sex;
}else{
throw new InputSexException("性别不合法" + sex);
}
}
public void setAge(int age) {
if(age > 0 && age < 130){
this.age = age;
}else{
throw new InputAgeOutOfBoundsException("年龄不合法" + age);
}
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public static void main(String[] args) {
Student stu1 = new Student();
stu1.setName("赵四");
stu1.setAge(111);
try {
stu1.setSex('人');
} catch (InputSexException e) {
e.printStackTrace();
}
System.out.println("程序结束");
}
}package com.atguigu.test6;
/**
* 当JDK提供的异常不能满足开发需求时,我们可以自定义异常
* 自定义异常步骤:
* 1.继承异常父类 Throwable 、Exception 、RuntimeException 三者其中之一
* 2.调用父类中的有参构造完成异常信息的初始化
*/
public class InputAgeOutOfBoundsException extends RuntimeException{
public InputAgeOutOfBoundsException(String message) {
super(message);
}
}package com.atguigu.test6;
public class InputSexException extends Exception{
public InputSexException(String message) {
super(message);
}
}