递归
方法直接或者间接调用本身
案例1 递归求5的阶乘
java
public class RecursionDemo1 {
public static void main(String[] args) {
//递归 方法直接或间接调用本身
System.out.println(calculateMulti(5));
}
private static int calculateMulti(int i) {
if(i == 1)
{
return 1;
}
return i * calculateMulti(i-1);
//120
}
}
递归出口条件:1的阶乘是1,求5的阶乘其实下一步是5乘4的阶乘,而4的阶乘就可以用阶乘计算方法(i-1)代替
栈内存示意图
递归调用jc方法,到最后一次调用jc方法的时候,将结果return1回给上一次调用的jc(num-1),最后就是2*1;3*2;4*6;5*24,retun给主方法120,程序运行结束
案例2 使用递归求1到n的和
用户输入n------递归调用求和的方法
java
public class RecursionDemo2 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入您想从1求和到多少:");
int n = sc.nextInt();
System.out.println(sum(n));
}
public static int sum(int n) {
if(n==1)
{
return 1;
}
return sum(n-1)+n;
}
}
出口定义为n==1时返回1,所以从n开始调用方法,只要n大于1,返回值就是n+加上方法(n-1)
案例3 不死神兔

递归方法调用参数是月份,假如说n是1和2就没有新兔子,就是一对,所以总数不变就为1
假设说递归调用方法为rabbit,那么rabbit(1)和rabbit(2)都是==1的,从第三月开始,rabbit都会产生新兔子,总兔子对数依次是1,1,2,3,5,8,可以发现从第三个月开始,是前两个月的和,3=2+1,5=2+3,那么rabbit3以上就可以用rabbit(i-2)+rabbit(i-1)进行表示并进行递归
java
public class RecursionDmoe3 {
public static void main(String[] args) {
System.out.println(rabbit(20));
}
public static int rabbit(int n) {
if(n == 1) {
return 1;
}
if(n == 2) {
return 1;
}
else {
return rabbit(n - 1) + rabbit(n - 2);
}
//6765
}
}
递归主要是找规律+定义好递归出口,不要死循环
案例4 猴子吃桃

递归出口条件就是n=10的时候,只剩下一个桃子,所以输入应为从哪一天到第十天
java
public class RecurisionDemo4
{
public static void main(String[] args)
{
System.out.println(peach(1));
}
public static int peach(int n)
{
if (n == 10)
{
return 1;
}
else {
return (peach(n+1)+1)*2;
}
}
}
除了第十天返回值为1之外,之前的每一天桃子的数量都是下一天桃子的数量先+1再×2
异常
程序在编译或者运行的时候出现的错误
异常体系

Error为严重级别问题,常见有栈内存溢出和堆内存溢出
我们常见的异常都为Exception类
其中分为RuntimeException及子类------运行时异常 和除RuntimeException之外的所有异常------编译时异常
编译时异常主要是提醒作用,虽然语法没有问题,但是输入参数容易出现错误。
异常的默认处理流程
- 出现异常,创建异常对象
- 异常从方法中出现的点抛出给调用者,调用者抛出给JVM虚拟机
- 虚拟机接收到异常对象之后,控制台直接输出异常信息数据
- java程序终止运行
异常处理方法
try------catch捕获异常
异常对象可以被捕获,不会抛出给虚拟机,java可以继续运行
java
public class exceptionDemo1 {
public static void main(String[] args) {
System.out.println("开始");
try {
System.out.println(10 / 0);
}catch (ArithmeticException e){//ArithmeticException e=new ArithmeticException()
System.out.println("捕获除0的运算异常");
}
System.out.println("结束");
}
// 开始
// 捕获除0的运算异常
// 结束
}
如果出现异常则catch会创建对象捕获try中new的异常对象,如果没有异常发生catch不工作。
java
public class exceptionDemo1 {
public static void main(String[] args) {
System.out.println("开始");
try {
int[] arr = null;
System.out.println(arr[8]);
System.out.println(10 / 0);
}catch (ArithmeticException e){//ArithmeticException e=new ArithmeticException()
System.out.println("捕获除0的运算异常");
}catch (NullPointerException e){
System.out.println("捕获空指针异常");
}
System.out.println("结束");
}
// 开始
// 捕获空指针异常
// 结束
可以捕获多个异常,如果还有其他异常可以使用父类引用Exception e捕获其他异常
需求 录入student信息
在输入年龄的时候,可以用Integer的parseInt方法将字符串转为整数,但是这里的输入可能出现异常,所以可以用try------catch加while循环的方法进行代码的维护
java
public class tryCatchDemo {
public static void main(String[] args) {
Student stu=new Student();
Scanner sc = new Scanner(System.in);
System.out.println("请输入学生姓名");
String name = sc.nextLine();
System.out.println("请输入学生年龄");
int age= 0;
while (true){
try {
age = Integer.parseInt(sc.nextLine());
break;
} catch (NumberFormatException e) {
System.out.println("年龄输入有误,请输入整数年龄");
}
}
stu.setName(name);
stu.setAge(age);
System.out.println(stu);
}
}

throw和throws抛出异常
throw用在方法中,后面跟着异常对象,用于抛出异常对象
throws用在方法名后面,起到声明作用
如果异常对象为编译时异常,必须使用throws声明;如果是运行时异常,则不需要写throws
java
public void setAge(int age) {
if (age < 0 || age > 100) {
throw new IllegalArgumentException("Age must be between 0 and 100");
}
else{
this.age = age;
}
}
java
public void setAge(int age)throws Exception {
if (age < 0 || age > 100) {
throw new Exception("Age must be between 0 and 100");
}
else{
this.age = age;
}
}

throw可以暴露异常,也可以在暴露之后用try------catch进行捕获
自定义异常
如果想自定义编译时异常,创建一个类继承Exception
如果想自定义运行时异常,创建一个类继承RunTimeException
初始化可以让父类帮忙,比如说刚才的学生年龄异常,就可以写为
java
public class StudentException extends RuntimeException {
public StudentException() {
}
public StudentException(String message) {
super(message);
}
}
java
public void setAge(int age) {
if (age < 0 || age > 100) {
throw new StudentException("Age must be between 0 and 100");
}
else{
this.age = age;
}
}

自定义异常能够正常将异常抛出