14java-递归&&异常

递归&&异常

递归

  • 方法自己调用自己
    • 直接递归:方法自己调用自己
    • 间接递归:方法调用其他方法,其他方法又回调方法自己

**注意:**递归如果没有控制好终止,会出现递归死循环,导致栈内存溢出现象

案例解析:

//求阶乘
public static int jc(int num) {
        if (num == 1) {
            return 1;
        } else {
            return num * jc(num - 1);
        }
    }
/*
有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问第二十个月的兔子对数为多少?
*/
public static int getreb(int month) {
        if (month == 1 || month == 2) {
            return 1;
        } else {
            return (getreb(month - 2)) + (getreb(month - 1));
        }
    }
递归解决问题的思路:
  • 把一个复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解

异常

​ 指的是程序在编译或执行过程中,出现的非正常的情况

异常体系

14java-递归&&异常_第1张图片

Error:

​ 系统级别问题、JVM退出等,代码无法控制。

Exception:
  • java.lang包下,称为异常类,它表示程序本身可以处理的问题
    • **RuntimeException及其子类:**运行时异常,编译阶段不会报错。 (空指针异常,数组索引越界异常)
    • 除RuntimeException之外所有的异常:编译时异常,编译期必须处理的,否则程序不能通过编译。 (日期格式化异常)。
编译时异常和运行时异常
  • **编译时异常:**是在编译成class文件时必须要处理的异常,也称之为受检异常
    • 不是RuntimeException或者其子类的异常,编译阶就报错,必须处理,否则代码不通过。
    • 编译时异常的作用:在编译阶段就爆出一个错误, 目的在于提醒
  • **运行时异常:**在编译成class文件时不需要处理,在运行字节码文件时可能出现的异常
    • 直接继承自RuntimeException或者其子类,编译阶段不会报错,运行时可能出现的错误。
异常的默认处理流程
  1. 虚拟机会在出现异常的代码那里自动的创建一个异常对象:ArithmeticException
  2. 异常会从方法中出现的点这里抛出给调用者,调用者最终抛出给JVM虚拟机
  3. 虚拟机接收到异常对象后,先在控制台直接输出异常信息数据
  4. 直接从当前执行的异常点干掉当前程序
  5. 后续代码没有机会执行了,因为程序已经噶了
默认异常处理机制
  • 创建一个异常对象,交给调用者处理
  • 最终会交给虚拟机处理
  • 虚拟机处理方式:将异常信息打印在控制台并停止虚拟机运行
异常处理方式
处理方式一 :try…catch…
  • 监视捕获异常,用在方法内部,可以将方法内部出现的异常直接捕获处理。
  • 这种方式还可以,发生异常的方法自己独立完成异常的处理,程序可以继续往下执行。
异常处理方式2 :throws
  • throws:用在方法上,可以将方法内部出现的异常抛出去给本方法的调用者处理。
try{
	// 可能出现异常的代码!
}catch (Exception e){
	e.printStackTrace();
	// 直接打印异常栈信息
}
Exception可以捕获处理一切异常类型!
  • 这种方式并不好,发生异常的方法自己不处理异常,如果异常最终抛出去给虚拟机将引起程序死亡。
方法 throws 异常1 ,异常2 ,异常3 ..{
}
两种方式的差别

throw:用在方法中,后面跟的是异常对象,是真正抛出异常对象的关键字

​ -编译时异常:必须写throws声明

​ -运行时异常:不需要编写throws声明

throws:用在方法声明上,后面跟的是异常类名,作用是声明此方法中存在异常

异常的两种处理方式,怎么选?

思路:看这个问题是否需要暴露出来

需要:抛出

不需要:try…catch…捕获异常

异常处理方式3 :前两者结合
  • 方法直接将异通过throws抛出去给调用者
  • 调用者收到异常后直接捕获处理
自定义异常
好处:
  • 可以使用异常的机制管理业务问题,如提醒程序员注意。
  • 同时一旦出现bug,可以用异常的形式清晰的指出出错的地方
自定义异常的分类
自定义编译时异常
  • 定义一个异常类继承Exception.
  • 重写构造器。
  • 在出现异常的地方用throw new 自定义对象抛出

**作用:**编译时异常是编译阶段就报错,提醒更加强烈,一定需要处理!

自定义运行时异常
  • 定义一个异常类继承RuntimeException.
  • 重写构造器。
  • 在出现异常的地方用throw new 自定义对象抛出!

**作用:**提醒不强烈,编译阶段不报错!!运行时才可能出现!!

Throwable
String getMessage();	//返回异常的错误原因
String toString();	//返回异常信息的简短描述
void printStackTrace();	//返回异常错误的完整信息
继承中子类重写父类方法的时候
        1. 如果父类的方法没有抛异常, 子类遇到了异常只能try...不能抛
        2. 子类不能抛出父类中没有的异常, 或者是比父类更大的异常

案例解析:

//建立学生类
public class Student {
    private String name;
    private int age;

    public Student() {
    }

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }
    
    public void setName(String name) {
        this.name = name;
    }
    
    public int getAge() {
        return age;
    }
    
    public void setAge(int age){
        if (age >= 0 && age <= 120) {
            this.age = age;
        }else {
            throw new StudentAgeException("年龄输入有误,请检查年龄范围是否在0-120之间");
        }
    }

    public String toString() {
        return "Student{name = " + name + ", age = " + age + "}";
    }
}
//建立学生类异常
public class StudentAgeException extends RuntimeException{
    public StudentAgeException() {
    }

    public StudentAgeException(String message) {
        super(message);
    }
}
//  键盘录入学生姓名年龄,将其封装成Student类
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        Student student = new Student();
        System.out.println("请输入姓名");
        student.setName(sc.nextLine());
        while (true) {
            try {
                System.out.println("请输入年龄");
                student.setAge(Integer.parseInt(sc.nextLine()));
                break;
            } catch (NumberFormatException e) {
                System.out.println("年龄输入有误,请重新输入");
            } catch (StudentAgeException e) {
                System.out.println(e.getMessage());
            }
        }
        System.out.println(student);
    }

你可能感兴趣的:(java,开发语言)