JavaSE进阶——day05

目录

1-递归

案例1:求阶乘

案例2:求1~n之间的数字之和(递归)

案例3:不死神兔(斐波那契数列)

递归的细节:

2-日期类

JDK8之前(今日学习)

Date类(时间)

SimpleDateFormat类(时间格式化)

练习

Calendar类(日历)

3-异常

异常体系

异常的处理方式

异常的默认处理流程

异常处理方案

练习

总结


1-递归


介绍:方法自己调用自己

  • 注意:设计递归的出口,如果没有设计出口

  • StackOverflowError:栈内存溢出

案例1:求阶乘

5 * 4 * 3 * 2 * 1

6 * 5 * 4 * 3 * 2 * 1

...

package com.lyl.method;
​
public class MethodDemo1 {
    public static void main(String[] args) {
        System.out.println(jiecheng(5));
    }
    /*
    定义方法求进阶:
    !5 :5*4的阶乘
    !4 :4*3的阶乘
    !3 :3*2的阶乘
    !2 :2*1的阶乘
    !1 :1
     */
    private static int jiecheng(int num) {
        if (num == 1) {
            return 1;
        } else {
            //思路:我要调用方法解决问题,发观自己这个方法,就是解决河题的方法,就递归调用
            return num * jiecheng(num - 1);
        }
    }
}

案例2:求1~n之间的数字之和(递归)

package com.lyl.method;
​
public class MethodDemo2 {
    public static void main(String[] args) {
        System.out.println(sum(5));
    }
​
    public static int sum(int num) {
        if (num == 1){
            return 1;
        }else {
            return num + sum(--num);
        }
    }
}

案例3:不死神兔(斐波那契数列)

描述:从前有一对小兔子,过了一个月之后可以长成大兔子,再过一个月又能生下一对小兔子...

-假如兔子不死,10个月后有多少对兔子...

package com.lyl.method;
​
public class MethodDemo3 {
    /*
         1 1 2 3 5 8 13 21
         从第三个月开始:兔子的对数,是前两月相加的和
     */
    public static void main(String[] args) {
        System.out.println(get(8));
    }
​
    public static int get(int month) {
        if (month == 1 || month == 2) {
            return 1;
        } else {
            //思路: 第month的数量=month-1 + month-2;
            return get(month - 1) + get(month - 2);
        }
    }
}
  • 需求:让D盘下所有的.java文件找出来

  • D:获取所有的文件和文件夹 文件:获取文件名,判断是否以.java为结尾文件夹:进入文件夹继续查找

递归的细节:

  • 直接递归

  • 间接递归(A调B,B调C,C调A),了解即可

2-日期类


  • 需求:注册XXX社交账户

    输入自己的生日: 1990-2-6

    • 计算出年龄

  • 需求:疯狂星期四

    周一,周二:不展示疯狂星期四的套餐

    周四:展示疯狂星期四的套餐

JDK8之前(今日学习)

  • Date类(时间)

注意:是在util包

package com.lyl.time;
​
import java.util.Date;
​
public class DateDemo1 {
    /*
    Date类代表时间
    1.构造方法:
    public Date():将当前时间封装为Date时间对象
     */
    public static void main(String[] args) {
        Date d1 = new Date();
        System.out.println(d1);
    }
}

输出结果:Sun Mar 26 10:23:49 CST 2023

package com.lyl.time;
​
import java.util.Date;
​
public class DateDemo1 {
    /*
    Date类代表时间
    1.构造方法:
    public Date():将当前时间封装为Date时间对象
    public Date(long time):根据传入的毫秒值,来封装时间对象
     */
    public static void main(String[] args) {
        Date d1 = new Date();
        System.out.println(d1);
​
        Date d2 = new Date(1000L);
        System.out.println(d2);
    }
}

输出结果:Sun Mar 26 10:26:08 CST 2023 Thu Jan 01 08:00:01 CST 1970

package com.lyl.time;
​
import java.util.Date;
​
public class DateDemo1 {
    /*
    Date类代表时间
    1.构造方法:
    public Date():将当前时间封装为Date时间对象
    public Date(long time):根据传入的毫秒值,来封装时间对象
    2.成员方法:
    public long getTime():获取毫秒值
    public void setTime(long time):根据传入的毫秒值,来封装时间对象
     */
    public static void main(String[] args) {
        Date d1 = new Date();
        System.out.println(d1);
​
        Date d2 = new Date();   //Student stu = new Student();
        d2.setTime(1000);       //stu.setAge(23);
        System.out.println(d2);
​
        System.out.println(d1.getTime());
        System.out.println(d2.getTime()); // 时间原点 ~ 1970-1-1 00:00:01
​
        System.out.println(System.currentTimeMillis()); // 时间原点 ~ 此刻时间
    }
}
  • SimpleDateFormat类(时间格式化)

package com.lyl.time;
​
import java.text.SimpleDateFormat;
import java.util.Date;
​
public class SimpleDateFormatDemo1 {
    /*
    SimpleDateFormat:时间格式化
    构造方法:
      public SimpleDateFormat(String pattern):根据传入的字符串模式,来格式化时间对象
    常用成员方法:
      public String format(Date date)     将日期格式化成日期/时间字符串
     */
    public static void main(String[] args) {
        Date time = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
        String format = sdf.format(time);
        System.out.println(format);
    }
}

输出结果:2023年03月26日 10:37:51

// public Date parse(String source)    将参数中的日期字符串,解析为Date日期对象
public static void main(String[] args) throws ParseException {
    String s = "2008年8月8日";
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日");
    Date date = sdf.parse(s);
    System.out.println(date);
}

输出结果:Fri Aug 08 00:00:00 CST 2008

练习

  • 键盘录入用户生日,计算活了多少天

package com.lyl.time;
​
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Scanner;
​
public class BirthdayTest {
    /*
    需求:键盘录入用户的生日,程序计算出用户来到了这个世界多少天
            1.键盘录入生日(以字符串的形式接受)
                  String birthday;
            2.将生日字符串转换Date日期对象
                  Date birthdayDate
            3.创建Date对象,封装此刻的时间
                  Date todayDate
            4.计算附间差(毫秒)
                  todayDate.getTime()-birthdayDate.getTime();
            5.将毫秒值转换为天的单位
                  毫秒值/1000/60/60/24
     */
    public static void main(String[] args) throws ParseException {
        System.out.println("请输入生日(格式:xxxx年xx月xx日)");
        //1.键盘录入生日(以字符串的形式接受)
        String birthday = new Scanner(System.in).nextLine();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日");
        //2.将生日字符串转换Date日期对象
        Date birthdayDate = sdf.parse(birthday);
        //3.创建Date对象,封装此刻的时间
        Date todayDate = new Date();
        //4.计算附间差(毫秒)
        Long time = todayDate.getTime() - birthdayDate.getTime();
        //5.将毫秒值转换为天的单位
        System.out.println(time / 1000 / 60 / 60 /24);
    }
}
  • Calendar类(日历)

Calendar类是一个抽象类,用Calendar rightNow = Calendar.getInstance ();获取子类对象

package com.lyl.calendar;
​
import java.util.Calendar;
​
public class Test {
    /*
    Calendar类创建对象:
    static Calendar getInstance() :获取对象
    常用成员方法:
    public int get(int field) :根据传入的字段,获取对应的日历信息
            常用字段:
                    Calendar.YEAR :获取年
                    Calendar.MONTH :获取月 注意:月份是0~11,月份获取出来需要+1操作
                    Calendar.DAY_OF_MONTH :获取日
                    Calendar.DAY_OF_WEEK : 获取星期 注意:日 一 二 三 四 五 六
                                                   解决:使用查表法
                    Calendar.DAY_OF_YEAR : 获取一年中的多少天
     */
    public static void main(String[] args) {
        Calendar calendar = Calendar.getInstance();
        System.out.println(calendar.get(Calendar.YEAR));
        System.out.println(calendar.get(Calendar.MONTH)+1);
        System.out.println(calendar.get(Calendar.DAY_OF_MONTH));
        char[] weekDay = {' ','日','一','二','三','四','五','六'};
        //                 0   1    2   3    4    5   6    7
        int index = calendar.get(Calendar.DAY_OF_WEEK);
        System.out.println(weekDay[index]);
        System.out.println(calendar.get(Calendar.DAY_OF_YEAR));
    }
}

输出结果:2023 3 26 日 85

3-异常


  • 异常介绍:指的是程序在执行过程中,出现的非正常的情况,最终会导致JVM的非正常停止

    ArrayIndexOutofBoundsException ClassCastException NullPointerException ...

  • 异常学什么?

    能够看懂异常信息 掌握异常的两种处理方式 自定义异常

    • 从下往上慢慢看,看不懂异常信息就翻API

异常体系

Exception类的异常:编码可以解决。

  • 1.异常是什么? 

    异常是代码在编译或者执行的过程中可能出现的错误。

  • 2.异常分为几类?

    编译时异常、运行时异常。

  • 编译时异常:没有继承RuntimeExcpetion的异常,编译阶段就会出错

  • 运行时异常:继承自RuntimeException的异常或其子类,编译阶段不报错,运行可能报错

  • 3.学习异常的目的?

    避免异常的出现,同时处理可能出现的异常,让代码更稳健。

异常的处理方式

1,自己能够解决,自己处理

2,自己解决不了,找上级处理(抛出异常)

异常的默认处理流程

  1. 虚拟机会在出现异常的代码那里自动的创建一个异常对象:ArithmeticException

  2. 异常会从方法中出现的点这里抛出给调用者,调用者最终抛出给VM虚拟机

  3. 虚拟机接收到异常对象后,先在控制台直接输出异常信息数据

  4. 直接从当前执行的异常点干掉当前程序

  5. 后续代码没有机会执行了,因为程序已经噶了

异常处理方案

异常的第一种处理方案:throws抛出异常

在方法的后面,编写throws关键字,再跟上异常类名

细节1:你调用的方法,如果抛出了异常,就需要继续声明throws抛出异常

细节2:如果一个方法中抛出的异常特别多,可以选择抛出一个大的异常

细节3:子类在重写父类方法的时候,不能抛出父类中没有的异常,或者是比父类更大的异常(父亲坏了,儿子不能比父亲还坏)

异常的第二种处理方案:try...catch

快捷键(IDEA开发工具):选中要包裹的代码,ctrl+alt+t

try{
可能会出现异常的代码
}catch(要捕获的异常类名对象名){
异常的处理方案
}

好处:不会将程序终止,后续的代码还可以继续执行

注意:1.如果编写了多个cath,最大的异常一定要放最后捕获

2.cath中可以同时捕获多个异常,中间用 | 隔开,但是不推荐。(无法具体明确是何异常)

练习

  • 以字符串的形式,从键盘录入学生的姓名和年龄,将数据封装为学生对象

package com.lyl.exception;
​
import com.lyl.domain.Student;
​
import java.util.Scanner;
​
public class ExceptionTest1 {
    public static void main(String[] args) {
        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("您的输入有误,请重新输入:");
            }
        }
​
        Student stu = new Student(name,age);
        System.out.println(stu);
    }
}

输出结果:

请输入学生姓名:

zhangsan

请输入学生年龄:

28.5

您的输入有误,请重新输入:

dfsd

您的输入有误,请重新输入:

23

Student{name = zhangsan, age = 23}

代码增强:

Student类中:

public Student(String name, int age) {
    this.name = name;
    setAge(age);
}
public void setAge(int age) {
    if (age >= 0 && age <= 120){
         this.age = age;
     }else {
         throw new RuntimeException("年龄有误,请检查是否为0~120之间");
     }
}

测试类中:

while (true) {
    try {
        age = Integer.parseInt(sc.nextLine());
        Student stu = new Student(name, age);
        System.out.println(stu);
        break;
    } catch (NumberFormatException e) {
        System.out.println("输入有误,请重新输入:");
    } catch (RuntimeException e) {
        System.out.println(e.getMessage());
    }
}

输出结果:

请输入学生姓名:

zhangsan

请输入学生年龄:

-23

年龄有误,请检查是否为0~120之间

23.5

输入有误,请重新输入:

asd

输入有误,请重新输入:

23 Student{name = zhangsan, age = 23}

总结

异常处理方式1——throws

throws:用在方法上,可以将方法内部出现的异常抛出去给本方法的调用者处理。

这种方式并不好,发生异常的方法自己不处理异常,如果异常最终抛出去给虚拟机将引起程序死亡。

异常处理方式2——try...catch...

监视捕获异常,用在方法内部,可以将方法内部出现的异常直接捕获处理。

这种方式还可以,发生异常的方法自己独立完成异常的处理,程序可以继续往下执行。

异常处理方式3——两者结合

自定义异常的必要?

●Java无法为这个世界上全部的问题提供异常类。

●如果企业想通过异常的方式来管理自己的某个业务问题,就需要自定义异常类了。

自定义异常的好处:

可以使用异常的机制管理业务问题,如提醒程序员注意。

同时一旦出现bug,可以用异常的形式清晰的指出出错的地方。

自定义异常的分类

1、自定义编译时异常

定义一个异常类继承Exception.

重写构造器。

在出现异常的地方用throw new自定义对象抛出

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

2、自定义运行时异常

定义一个异常类继承RuntimeException.

重写构造器。

在出现异常的地方用throw new自定义对象抛出!

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

e.printStackTrace();展示完整的异常信息,虽然是红色的字体,但是不会影响后续代码的执行!!!

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值