文章目录
异常
1. 概述
- 简单理解为,程序发生的错误信息。
- 异常:是用来封装错误信息的 对象 ,告知使用者。
- 组成部分: 提示信息,报错行号,异常类型。
2. 异常类型
-
异常的继承结构:
-
java.lang.Throwable
顶级父类;所有类,都是其子类。该类下有两个异常分支类Error;表示错误
和Exception;表示异常
。Error;
表示错误,例如:内存溢出,网络环境中断 ,或者 硬件系统错误; 调式代码无法修复的错误;Exception ;
表示异常;主要分成两大类:运行时异常RuntimeException
和 非运行时异常(检查异常);
3. 异常处理方法
- 异常的处理方式通常有两种: 捕获 和 向上抛出。
-
捕获:
try{}catch(){}
// 捕获方式: try { 需要捕获的code... ; }catch (异常类型 对象名){// Exception e; 这个e就是异常名(对象); //TODO 处理方案; e.printStackTrace(); //输出栈追踪信息打印处理。 ... }
-
向上抛出:
throws 异常类型名称;
throws 关键字, 声明这个方法可能会有异常,可能,倾向于!
如:throws Exception;//例如:当调用了一个异常的抛出方法时;调用位置可以不用做处理,继续向上抛出,也可以捕获异常! // 说明:下面只是举例子, main方法上面不能抛异常,一定要在调用前进行处理!因为main是程序唯一入口! public static void main(String[] args)throws Exception{ }
3.1 异常处理案例
- 准备开始写 Bug 代码!
- 两种写法的,除法程序。
public class Demo {
public static void main(String[] args) {
//1. 静态修饰的方法 类名.方法名 调用。
int method = Exception_Text.method(3, 0);
System.out.println(method); // java.lang.ArithmeticException: / by zero
Exception_Text.method(); //java.util.InputMismatchException
}
}
class Exception_Text{
/**
* 静态方法
* 根据传入的参数 计算除法。
* @param num_1
* @param num_2
*/
public static int method(int num_1,int num_2){
int num = num_1/num_2;
return num;
}
/**
* 无参方法
* 除法计算
*/
public static void method(){
//手动接受输入 数字
System.out.println("请输入第一个数字");
int num_1 = new Scanner(System.in).nextInt();
System.out.println("请输入第二个数字");
int num_2 = new Scanner(System.in).nextInt();
//除法运算
int num = num_1/num_2;
System.out.println(num);
}
}
3.1.1 办法一: 捕获异常
- 使用
try{}catch(){}
去捕获异常,有两种方式。- 知道, 出现异常名称,可以捕获单个,也可以捕获多个。
- 不知道, 出现的异常名称。 多态思想抛出父类异常。
public class Demo {
public static void main(String[] args) {
/*使用try{}catch(){}处理异常*/
//1.知道出现的异常名称
try{
int method = Exception_Test.method(3, 0);
System.out.println(method); // java.lang.ArithmeticException: / by zero
}catch (ArithmeticException e){
System.out.println("异常名称 "+ e);
//TODO 可以给一个解决方法
System.out.println("解决方案:分母不能为 0");
}
//1.1 捕获多个异常
try{
Exception_Test.method();
}catch (ArithmeticException ar){
System.out.println("分母不能为0");
}catch (InputMismatchException ie){
System.out.println("不能输入小数");
}
//2.当异常类型多且不知道名称时
try {
//Exception_Test.method(); //java.util.InputMismatchException
}catch (Exception e){ //相当于 多态思想抛出父类异常,Exception e = new ArithmeticException();
System.out.println("异常名称 "+e);
System.out.println("不能出现小数,或者分母为0");
}
}
}
class Exception_Test{
/**
* 静态方法
* 根据传入的参数 计算除法。
* @param num_1
* @param num_2
*/
public static int method(int num_1,int num_2){
int num = num_1/num_2;
return num;
}
/**
* 无参方法
* 除法计算
*/
public static void method(){
//手动接受输入 数字
System.out.println("请输入第一个数字");
int num_1 = new Scanner(System.in).nextInt();
System.out.println("请输入第二个数字");
int num_2 = new Scanner(System.in).nextInt();
//除法运算
int num = num_1/num_2;
System.out.println(num);
}
}
3.1.2 办法二: 抛出异常
- 使用关键字
throws
,抛出异常。- 知道名字,可以抛出单个异常,或者多个异常。
- 不知道名字, 抛出父类异常。
public class Demo2 {
public static void main(String[] args) {
// 处理两种形式 ,往上抛,或者 捕获。
try {
Exception_Test2.method();//当你调用该方法时候会提示你,需要处理此异常。
} catch (Exception e) {
e.printStackTrace();
}
}
}
class Exception_Test2{
/**
* 静态方法
* 根据传入的参数 计算除法。
* @param num_1
* @param num_2
*/
public static int method(int num_1,int num_2) throws ArithmeticException{
int num = num_1/num_2;
return num;
}
/**
抛出异常的,知道该程序肯定有问题,但是有啥问题不知道。
*/
public static void method() throws Exception{
//手动接受输入 数字
System.out.println("请输入第一个数字");
int num_1 = new Scanner(System.in).nextInt();
System.out.println("请输入第二个数字");
int num_2 = new Scanner(System.in).nextInt();
//除法运算
int num = num_1/num_2;
System.out.println(num);
}
}
4. 自定义异常
- 自己定义一个 相亲异常。
- 使用关键字
throw
主观抛出异常。
- 使用关键字
public class Demo3 {
public static void main(String[] args) {
System.out.println("请问你有车么?");
String answer = new Scanner(System.in).next();
System.out.println("请问你有房么?");
String answer2 = new Scanner(System.in).next();
checklove(answer,answer2);
}
/**
*
* @param car
* @param house
* @throws Love_ruleException
*/
public static void checklove(String car,String house) throws Love_ruleException {
if (car.equals("n")&&house.equals("n")){
throw new Love_ruleException("听妈妈的话,晚点在恋爱吧");// throw 此处需要抛出异常
}else {
System.out.println("遇见,真爱了");
}
}
}
//自定义异常需要继承顶级父类
// Exception 必须处理
// RuntimeException 可以不处理
class Love_ruleException extends RuntimeException{
//利用构造器返回异常信息
public Love_ruleException(String message) {
super(message);
}
}
5. 扩展
5.1 Exception 和 RuntimeException
-
异常在java中要当成一个 对象来看待! :
- 当一个异常用
throws
声明的时候,要注意看这个异常是否是RuntimeException
的异常,如果是声明了也可以不用处理! - 如果声明是
Exception
,就一定要处理,在编译期间就会异常!
- 当一个异常用
-
什么是运行时异常?什么是非运行时异常?:
- 运行时异常 都是
RuntimeException
类及其子类异常,通俗理解就是 一般由程序逻辑不够严谨,而造成的错误引起,程序应该从逻辑角度尽可能避免这类异常的发生。相当于在 java.exe时,程序中可以选择捕获处理,也可以不处理。 如NullPointerException、IndexOutOfBoundsException,ArithmeticException
, - 非运行时异常(检查异常)是指
RuntimeException
以外的异常 。
老吴认为:javac.exe之前,就是逻辑代码,没有错误,而是因为外界因素引起的异常,另一种理解,写代码时,编辑器上出现的“红线”,java编译器要求我们必须用 异常处理方法 处理的。如:文件缺失等。,从程序语法角度讲 是必须进行处理的异常。如IOException、,SQLException
等以及用户自定义的 Exception 异常。
- 运行时异常 都是
public class ExceptionDemo {
public static void main(String[] args) {
int a =10;
int b = 0;
if (b!=0){ // 可以选择自己处理,也可以不处理!
method(a, b);// 运行时异常,可以处理,也可以不处理!
}
//1.假设上面方法调用结束之后,后面code还可以执行!
System.out.println("程序执行结束end...");
// 2.1 当方法抛出的是Exception当你调用方法时,编译器会提示你必须处理!
try{
method2(a,b); // 这如果不处理就是小红线!
}catch (Exception e){
e.printStackTrace();//将异常打印控制台!程序可以继续执行下去!!
}
System.out.println(" Exception over..."); // 可以执行到这!
}
/**
* 1.RuntimeExcetion运行时异常,也可以这么理解!就是在编译器调用javac.exe时没有问题!可能出现问题!也不一定出现问题!
* 假设写方法这个人, 比较懒! 没处理!
* 其实 throws就是声明,向上抛出异常,告诉调用者这有异常,需要你根据实际情况处理(让调用者处理)!
* ps:不抛出,不告诉!不处理这个方法有错么?也没错!谁知道你要怎么使用!!!(但是不建议!)
*/
// 最起码要告知使用者,这会出现异常
// 如:public static void method(int a,int b) throws ArithmeticException {
// 如:public static void method(int a,int b) throws RumtimeException{
public static void method(int a,int b) {
int result = a/b;
System.out.println("result结果:"+result);
}
/**
* 2.Exception 编译时异常!
* 要么1.捕获。2抛出两种“必须”选一个!
* 注意: throws Exception 时 调用的方法必须处理!!
*/
private static void method2(int a, int b) throws Exception {
int result = a/b;
System.out.println("result结果:"+result);
}
}
输出结果:
程序执行结束end......
Exception over...
java.lang.ArithmeticException: / by zero
at com.demo.ExceptionDemo.method2(ExceptionDemo.java:48)
at com.demo.ExceptionDemo.main(ExceptionDemo.java:22)
5.2 面试题:throw 和 throws区别!
-
throws
关键字,方法上:跟异常类的名字!- 表示此方法会抛出异常,需要由本方法的调用者来处理这些异常(这些异常可能发生,也可能不发生)。
public static void main(String arg[]) throws 异常类型名字{}
-
throw
关键字方法内部:跟异常对象的引用;throw 异常对象的引用变量
- 表示此处抛出异常,由方法体内的语句处理(肯定发生异常)。
throw new Exception();