day09-常用API&异常

1.时间日期类

1.1 Date类(应用)

  • 计算机中时间原点

    1970年1月1日 00:00:00

  • 时间换算单位

    1秒 = 1000毫秒

  • Date类概述

    Date 代表了一个特定的时间,精确到毫秒

  • Date类构造方法

    方法名说明
    public Date()分配一个 Date对象,并初始化,以便它代表它被分配的时间,精确到毫秒
    public Date(long date)分配一个 Date对象,并将其初始化为表示从标准基准时间起指定的毫秒数
  • 示例代码

    public class DateDemo01 {
        public static void main(String[] args) {
            //public Date():分配一个 Date对象,并初始化,以便它代表它被分配的时间,精确到毫秒
            Date d1 = new Date();
            System.out.println(d1);
    
            //public Date(long date):分配一个 Date对象,并将其初始化为表示从标准基准时间起指定的毫秒数
            long date = 1000*60*60;
            Date d2 = new Date(date);
            System.out.println(d2);
        }
    }
    

1.2 Date类常用方法(应用)

  • 常用方法

    方法名说明
    public long getTime()获取的是日期对象从1970年1月1日 00:00:00到现在的毫秒值
    public void setTime(long time)设置时间,给的是毫秒值
  • 示例代码

    public class DateDemo02 {
        public static void main(String[] args) {
            //创建日期对象
            Date d = new Date();
    
            //public long getTime():获取的是日期对象从1970年1月1日 00:00:00到现在的毫秒值
    //        System.out.println(d.getTime());
    //        System.out.println(d.getTime() * 1.0 / 1000 / 60 / 60 / 24 / 365 + "年");
    
            //public void setTime(long time):设置时间,给的是毫秒值
    //        long time = 1000*60*60;
            long time = System.currentTimeMillis();
            d.setTime(time);
    
            System.out.println(d);
        }
    }
    

1.3 SimpleDateFormat类(应用)

  • SimpleDateFormat类概述

    ​ SimpleDateFormat是一个具体的类,用于以区域设置敏感的方式格式化和解析日期

    ​ 我们重点学习日期格式化和解析

  • SimpleDateFormat类构造方法

    方法名说明
    public SimpleDateFormat()构造一个SimpleDateFormat,使用默认模式和日期格式
    public SimpleDateFormat(String pattern)构造一个SimpleDateFormat使用给定的模式和默认的日期格式
  • SimpleDateFormat类的常用方法

    • 格式化(从Date到String)
      • public final String format(Date date):将日期格式化成日期/时间字符串
    • 解析(从String到Date)
      • public Date parse(String source):从给定字符串的开始解析文本以生成日期
  • 示例代码

    /**
     * 日期格式转换
     */
    public class Demo2 {
        public static void main(String[] args) throws ParseException {
    
    
            //定义日期格式转换类   yyyy-MM-dd HH:mm:ss
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            Date date = new Date();
            //Date   ->   String
            String format = sdf.format(date);
            System.out.println(format);
    
            //2022-04-20 09:51:48日期字符串,转换为Date
            String datestr = "2022-04-20 09:51:48";
    
            //String   ->  Date
            Date parse = sdf.parse(datestr);
            System.out.println(parse);
    
            //y  年  M  月   d 日  H 小时  m分  s秒
            //日期之间的连接符可随便定义--  有一定的意义
            SimpleDateFormat sdf1 = new SimpleDateFormat("yy年MM-dd****HH1mm:ss");
            Date d1 = new Date();
            String format1 = sdf1.format(d1);
            System.out.println(format1);
        }
    }
    

tips:一个格式串只能转换一种格式的日期,不然报异常。

1.4 时间日期类练习 (应用)

  • 需求

    秒杀开始时间是2020年11月11日 00:00:00,

    结束时间是2020年11月11日 00:10:00,

    用户小贾下单时间是2020年11月11日 00:03:47,

    用户小皮下单时间是2020年11月11日 00:10:11,

    判断用户有没有成功参与秒杀活动

  • 实现步骤

    1. 判断下单时间是否在开始到结束的范围内
    2. 把字符串形式的时间变成毫秒值
  • 代码实现

    public class DateDemo5 {
        public static void main(String[] args) throws ParseException {
            //开始时间:2020年11月11日 0:0:0
            //结束时间:2020年11月11日 0:10:0
    
            //小贾2020年11月11日 0:03:47
            //小皮2020年11月11日 0:10:11
    
            //1.判断两位同学的下单时间是否在范围之内就可以了。
    
            //2.要把每一个时间都换算成毫秒值。
    
            String start = "2020年11月11日 0:0:0";
            String end = "2020年11月11日 0:10:0";
    
            String jia = "2020年11月11日 0:03:47";
            String pi = "2020年11月11日 0:10:11";
    
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
            long startTime = sdf.parse(start).getTime();
            long endTime = sdf.parse(end).getTime();
    
    //        System.out.println(startTime);
    //        System.out.println(endTime);
            long jiaTime = sdf.parse(jia).getTime();
            long piTime = sdf.parse(pi).getTime();
    
            if(jiaTime >= startTime && jiaTime <= endTime){
                System.out.println("小贾同学参加上了秒杀活动");
            }else{
                System.out.println("小贾同学没有参加上秒杀活动");
            }
    
            System.out.println("------------------------");
    
            if(piTime >= startTime && piTime <= endTime){
                System.out.println("小皮同学参加上了秒杀活动");
            }else{
                System.out.println("小皮同学没有参加上秒杀活动");
            }
    
        }
      
    }
    

2.递归

2.1 递归【应用】

  • 递归的介绍

    • 以编程的角度来看,递归指的是方法定义中调用方法本身的现象。
    • 把一个复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解。
    • 递归策略只需少量的程序就可描述出解题过程所需要的多次重复计算。
  • 递归的基本使用

  • 1- 100之间的和。

    /**
     * 1- 100之间的和。
     */
    public class Demo1 {
        public static void main(String[] args) {
            int s = getSum(5);
            System.out.println(s);
        }
        //1-100  1+2   2+3  把计算规模降低到最小。用小规模解决大规模问题
        private static int getSum(int i) {
    //        1-100
    //        100 + 99   i=100 +    100-1
    //             +98   i=199 +    98
    //                +97
    //                +96
            if(i==1){
                return 1;//程序出口
            }else {
                //1+2+3+4+5
                return i+getSum(i-1);//递归会一层一层的进去,到底后(出口),在返回来一层一层计算
            }
        }
    }
    
    
  • 递归的注意事项

    • 递归一定要有出口。否则内存溢出。
    • 递归虽然有出口,但是递归的次数也不宜过多。否则内存溢出。

2.2 递归求阶乘【应用】

  • 案例需求

    ​ 用递归求5的阶乘,并把结果在控制台输出。

    5!=5*4*3*2*1
    6!=6*5*4*3*2*1
    
  • 代码实现

    /**
     * 用递归求5的阶乘,并把结果在控制台输出。
     */
    public class Demo2 {
        public static void main(String[] args) {
            int r = jc(5);
            System.out.println(r);
        }
        private static int jc(int i) {
    //        1*2
    //        1*2*3
    //        1*2*3*4
    //        1*2*3*4*5
            //出口
            if(i==1){
                return 1;//底
            }else {
                return i*jc(i-1);//先进入到底,在反过来计算
            }
        }
    }
    
  • 内存图

    在这里插入图片描述

2.2 递归排序【理解】

递归调用是用相同的方法去解决更小的问题,直到问题规模小于或等于某个边界条件时,不再进行递归(递归的出口),而是直接处理,然后不断向下执行函数返回结果。

  • 分治法
  1. 当问题小到一定规模时,可以直接求解;一个一个 两两比较 44比较 88比较形成一个新的数字。

2. 当问题规模较大时,可以分解为若干个相互独立的子问题,这些子问题与原问题具有相同的特征。若不能直接解决,则可分别递归求解;

3. 原问题的解是子问题的解的组合。

/**
 * 归并排序
 *
 * @param array
 * @return
 */
public static int[] MergeSort(int[] array) {
    if (array.length < 2) return array;//分治  对折小于两个,只有一个元素无法对折。
    int mid = array.length / 2;//去取中间数的索引
    int[] left = Arrays.copyOfRange(array, 0, mid);
    int[] right = Arrays.copyOfRange(array, mid, array.length);
    return merge(MergeSort(left), MergeSort(right));
}
/**
 * 归并排序——将两段排序好的数组结合成一个排序数组
 *
 * @param left
 * @param right
 * @return
 */
public static int[] merge(int[] left, int[] right) {
    int[] result = new int[left.length + right.length];
    for (int index = 0, i = 0, j = 0; index < result.length; index++) {
        //比较 赋值
        if (i >= left.length)
            result[index] = right[j++];
        else if (j >= right.length)
            result[index] = left[i++];
        else if (left[i] > right[j])
            result[index] = right[j++];
        else
            result[index] = left[i++];
    }
    return result;
}

[十大经典排序算法最强总结(含JAVA代码实现) - 郭耀华 - 博客园 (cnblogs.com)](https://www.cnblogs.com/guoyaohua/p/8600214.html#:~:text=十大经典排序算法最强总结(含JAVA代码实现) 1 、排序算法说明 2 、冒泡排序(Bubble Sort) 3 、选择排序(Selection,、计数排序(Counting Sort) 10 、桶排序(Bucket Sort) More items… )

3.数组的高级操作

3.1 二分查找 (理解)

  • 二分查找概述

    查找指定元素在数组中的位置时,以前的方式是通过遍历,逐个获取每个元素,看是否是要查找的元素,这种方式当数组元素较多时,查找的效率很低。

    二分查找也叫折半查找,每次可以去掉一半的查找范围,从而提高查找的效率。

  • 前提

    数组{1,2,3,4,5,6,7,8,9,10},必须是顺序数组。

  • 需求

    在数组{1,2,3,4,5,6,7,8,9,10}中,查找某个元素的位置。

  • 实现步骤

    1. 定义两个变量,表示要查找的范围。默认min = 0 ,max = 最大索引
    2. 循环查找,但是min <= max
    3. 计算出mid的值
    4. 判断mid位置的元素是否为要查找的元素,如果是直接返回对应索引
    5. 如果要查找的值在mid的左半边,那么min值不变,max = mid -1.继续下次循环查找
    6. 如果要查找的值在mid的右半边,那么max值不变,min = mid + 1.继续下次循环查找
    7. 当min > max 时,表示要查找的元素在数组中不存在,返回-1.
  • 代码实现

    public class MyBinarySearchDemo {
        public static void main(String[] args) {
            int [] arr = {1,2,3,4,5,6,7,8,9,10};
            int number = 11;
    
            //1,我现在要干嘛? --- 二分查找
            //2.我干这件事情需要什么? --- 数组 元素
            //3,我干完了,要不要把结果返回调用者 --- 把索引返回给调用者
            int index = binarySearchForIndex(arr,number);
            System.out.println(index);
        }
    
        private static int binarySearchForIndex(int[] arr, int number) {
            //1,定义查找的范围
            int min = 0;
            int max = arr.length - 1;
            //2.循环查找 min <= max
            while(min <= max){
                //3.计算出中间位置 mid
                int mid = (min + max) >> 1;
                //mid指向的元素 > number
                if(arr[mid] > number){
                    //表示要查找的元素在左边.
                    max = mid -1;
                }else if(arr[mid] < number){
                    //mid指向的元素 < number
                    //表示要查找的元素在右边.
                    min = mid + 1;
                }else{
                    //mid指向的元素 == number
                    return mid;
                }
            }
            //如果min大于了max就表示元素不存在,返回-1.
            return -1;
        }
      
    }
    
  • 注意事项

    有一个前提条件,数组内的元素一定要按照大小顺序排列,如果没有大小顺序,是不能使用二分查找法的。

3.2 冒泡排序 (理解)

  • 冒泡排序概述

    一种排序的方式,对要进行排序的数据中相邻的数据进行两两比较,将较大的数据放在后面,依次对所有的数据进行操作,直至所有数据按要求完成排序

    如果有n个数据进行排序,总共需要比较n-1次

    每一次比较完毕,下一次的比较就会少一个数据参与

  • 代码实现

    public class MyBubbleSortDemo2 {
        public static void main(String[] args) {
            int[] arr = {3, 5, 2, 1, 4};
            //1 2 3 4 5
            bubbleSort(arr);
        }
    
        private static void bubbleSort(int[] arr) {
            //外层循环控制的是次数 比数组的长度少一次.
            for (int i = 0; i < arr.length -1; i++) {
                //内存循环就是实际循环比较的
                //-1 是为了让数组不要越界
                //-i 每一轮结束之后,我们就会少比一个数字.
                for (int j = 0; j < arr.length - 1 - i; j++) {
                    if (arr[j] > arr[j + 1]) {
                        int temp = arr[j];
                        arr[j] = arr[j + 1];
                        arr[j + 1] = temp;
                    }
                }
            }
    
            printArr(arr);
        }
    
        private static void printArr(int[] arr) {
            for (int i = 0; i < arr.length; i++) {
                System.out.print(arr[i] + " ");
            }
            System.out.println();
        }
      
    }
    

3.3 Arrays (应用)

  • Arrays的常用方法

    方法名说明
    public static String toString(int[] a)返回指定数组的内容的字符串表示形式
    public static void sort(int[] a)按照数字顺序排列指定的数组
    public static int binarySearch(int[] a, int key)利用二分查找返回指定元素的索引
    public static int[] copyOfRange(int[] original,int form,int to)将指定数组的指定范围复制到新数组中。
  • 示例代码

    public class MyArraysDemo {
              public static void main(String[] args) {
    
    //| public static String toString(int[] a)   | 返回指定数组的内容的字符串表示形式   |
    //        int[] arr = {3,2,1};
    //        String s = Arrays.toString(arr);
    //        System.out.println(s);
    
    
    //| public static void sort(int[] a) | 按照数字顺序排列指定的数组  |
    //        int[] arr = {3,2,1,4,6,5};
    //        Arrays.sort(arr);
    //        System.out.println(Arrays.toString(arr));
    //| public static int binarySearch(int[] a, int key)  | 利用二分查找返回指定元素的索引  |
    //        int[] arr = {3,2,1,4,6,5};//无序的不能
    //        int[] arr = {1,2,3,4,5,6,7};//有序
    //        int i = Arrays.binarySearch(arr, 8);//-7查的值大于数列最大值,返回长度+1的负数
    //        int i = Arrays.binarySearch(arr, 4);//3
    //        int i = Arrays.binarySearch(arr, -2);//-1查找的值小于列的最小值, 返回-1
            //返回为负数,就是找不到!
    //        System.out.println("index="+i);
    
    
    //| public static int[] copyOfRange(int[] original,int form,int to) | 将指定数组的指定范围复制到新数组中。 |
    
            int[] arr = {1,2,3,4,5,6,7};
            int[] ints = Arrays.copyOfRange(arr, 2, 4);//从2索引开始,到4  [2,4)
            System.out.println(Arrays.toString(ints));
    
        }
    }
      }
    
  • 工具类设计思想

    • 我们已经学过的工具类
    • Objects Arrays Math等
    1. 构造方法用 private 修饰
    2. 成员用 public static 修饰

4.异常

异常概述

异常处理方式

自定义异常

4.1 异常(记忆)

  • 异常的概述

    ​ 异常就是程序出现了不正常的情况

    /**
     * 演示异常
     */
    public class EDemo1 {
        public static void main(String[] args) throws ParseException {
    
            //写代码不报错,运行报错!!!
            //  运行时异常
    
    //        String s = null;
    //        System.out.println(s.length());//java.lang.NullPointerException
    
    //        int[] arr = {1,2,3};
    //        System.out.println(arr[4]);//java.lang.ArrayIndexOutOfBoundsException
    
    //        BigDecimal b1 = new BigDecimal("10.0");
    //        BigDecimal b2 = new BigDecimal("3.0");
    //        BigDecimal divide = b1.divide(b2);//java.lang.ArithmeticException
    //        System.out.println(divide);
    
            //必须要处理的错误,处理了以后才能执行
            // 编译时异常
    
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            String s = "2020-02-12";
            Date parse = sdf.parse(s);//这个问题只有处理掉才能执行
            System.out.println(parse);
    
        }
    }
    
  • 异常的体系结构

    在这里插入图片描述

4.2 编译时异常和运行时异常的区别(记忆)

  • 编译时异常

    • 都是Exception类及其子类
    • 必须显示处理,否则程序就会发生错误,无法通过编译
  • 运行时异常

    • 都是RuntimeException类及其子类
    • 无需显示处理,也可以和编译时异常一样处理
  • 图示

    在这里插入图片描述

4.3 JVM默认处理异常的方式(理解)

  • 如果程序出现了问题,我们没有做任何处理,最终JVM 会做默认的处理,处理方式有如下两个步骤:
    • 把异常的名称,错误原因及异常出现的位置等信息输出在了控制台
    • 程序停止执行

4.4 查看异常信息 (理解)

控制台在打印异常信息时,会打印异常类名,异常出现的原因,异常出现的位置

我们调bug时,可以根据提示,找到异常出现的位置,分析原因,修改异常代码2

在这里插入图片描述

4.5 throws方式处理异常(应用)

  • 概念:

声明异常。

自己不做处理,让程序编译时不报错,把异常交给调用者处理。

  • 格式:
public void 方法() throws 异常类名 {
    
}
  • 示例代码

    • 运行时异常(一般不用)
    • 编译时异常
/**
 * 演示异常  throws
 * 如果出现问题,再次交给jvm处理。。。,默认机制。
 */
public class EDemo2 {
    public static void main(String[] args) throws ParseException{
        //必须要处理的错误,处理了以后才能执行
        // 编译时异常

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String s = "2020/02/12";
        Date parse = sdf.parse(s);
        System.out.println(parse);
    }
}
  • 注意事项

    • 这个throws格式是跟在方法的括号后面的
    • 编译时异常必须要进行处理,两种处理方案:try…catch …或者 throws,如果采用 throws 这种方案,在方法上进行显示声明,将来谁调用这个方法谁处理。
    • 运行时异常因为在运行时才会发生,所以在方法后面可以不写,运行时出现异常默认交给jvm处理。

4.6 throw抛出异常 (应用)

主动抛出异常。通知别人,我有可能有问题。

  • 格式

    throw new 异常();

  • 注意

    这个格式是在方法内的,表示当前代码手动抛出一个异常,下面的代码不用再执行了。

  • throws和throw的区别。

    throwsthrow
    用在方法声明后面,跟的是异常类名用在方法体内,跟的是异常对象名
    调用的时候,别人声明了,我们必须跟着声明。如果不声明那么必须处理掉
    表示声明异常,调用该方法有可能会出现这样的异常表示手动抛出异常对象,由方法体内的语句处理
  • 示例代码

    • 模拟数组 空指针异常。
    public class ExceptionDemo8 {
        public static void main(String[] args) {
            //int [] arr = {1,2,3,4,5};
            int [] arr = null;
            printArr(arr);//就会 接收到一个异常.
                            //我们还需要自己处理一下异常.
        }
    
        private static void printArr(int[] arr) {
            if(arr == null){
                //调用者知道成功打印了吗?
                //System.out.println("参数不能为null");
                throw new NullPointerException(); //当参数为null的时候
                                                //手动创建了一个异常对象,抛给了调用者,产生了一个异常
            }else{
                for (int i = 0; i < arr.length; i++) {
                    System.out.println(arr[i]);
                }
            }
        }
    
    }
    

4.7 try-catch方式处理异常(应用)

  • 定义格式

    try {
    	可能出现异常的代码;
    } catch(异常类名 变量名) {
    	异常的处理代码;
    }
    
  • 执行流程

    • 程序从 try 里面的代码开始执行
    • 出现异常,就会跳转到对应的 catch 里面去执行
    • 执行完毕之后,程序还可以继续往下执行
  • 示例代码

    public class ExceptionDemo01 {
        public static void main(String[] args) {
            System.out.println("开始");
            method();
            System.out.println("结束");
        }
    
        public static void method() {
            try {
                int[] arr = {1, 2, 3};
                System.out.println(arr[3]);
                System.out.println("这里能够访问到吗");
            } catch (ArrayIndexOutOfBoundsException e) {
                System.out.println("你访问的数组索引不存在,请回去修改为正确的索引");
            }
        }
    }
    
  • 注意

    1. 如果 try 中没有遇到问题,怎么执行?

      会把try中所有的代码全部执行完毕,不会执行catch里面的代码

    2. 如果 try 中遇到了问题,那么 try 下面的代码还会执行吗?

      那么直接跳转到对应的catch语句中,try下面的代码就不会再执行了
      当catch里面的语句全部执行完毕,表示整个体系全部执行完全,继续执行下面的代码

    3. 如果出现的问题没有被捕获,那么程序如何运行?

      那么try…catch就相当于没有写.那么也就是自己没有处理.
      默认交给虚拟机处理.

    4. 同时有可能出现多个异常怎么处理?

      出现多个异常,那么就写多个catch就可以了.
      注意点:如果多个异常之间存在子父类关系.那么父类一定要写在下面

      ​ 如果不知道子父类关系,根据IDEA提示调整。

4.8 try-catch-finally

finally{代码块}

不管有没有异常都会执行finally里面的代码。

语法

try{}finally{}

try{}catch(异常类 参数名){}finally{}

格式一:
try {
    System.out.println(1);
    //可能出现异常的代码
    int arr[]  = new int[5];
    System.out.println(arr[6]);
}finally {
    System.out.println("宇航员安全!");
}

格式二:
try {
    System.out.println(1);
    //可能出现异常的代码
    int arr[]  = new int[5];
    System.out.println(arr[6]);
}catch (ArithmeticException ex){
    System.out.println("可以控制的异常ArithmeticException");
}finally {
    System.out.println("宇航员安全!");
}

4.9 Throwable成员方法(应用)

  • 常用方法

    方法名返回此 throwable 的详细消息字符串说明
    public String getMessage()返回此 throwable 的详细消息字符串
    public String toString()返回此可抛出的简短描述
    public String getCause()返回此 throwable 的异常原因。
    public void printStackTrace()把异常的错误信息输出在控制台
  • 示例代码

    public class ExceptionDemo02 {
        public static void main(String[] args) {
            System.out.println("开始");
            method();
            System.out.println("结束");
        }
    
        public static void method() {
            try {
                int[] arr = {1, 2, 3};
                System.out.println(arr[3]); //new ArrayIndexOutOfBoundsException();
                System.out.println("这里能够访问到吗");
            } catch (ArrayIndexOutOfBoundsException e) { //new ArrayIndexOutOfBoundsException();
    //            e.printStackTrace();
    
                //public String getMessage():返回此 throwable 的详细消息字符串
    //            System.out.println(e.getMessage());
                //Index 3 out of bounds for length 3
    
                //public String toString():返回此可抛出的简短描述
    //            System.out.println(e.toString());
                //java.lang.ArrayIndexOutOfBoundsException: Index 3 out of bounds for length 3
    
                //public void printStackTrace():把异常的错误信息输出在控制台
                e.printStackTrace();
    //            java.lang.ArrayIndexOutOfBoundsException: Index 3 out of bounds for length 3
    //            at com.gaohe_02.ExceptionDemo02.method(ExceptionDemo02.java:18)
    //            at com.gaohe_02.ExceptionDemo02.main(ExceptionDemo02.java:11)
    
            }
        }
    }
    

在这里插入图片描述

try{}catch(){}

try{}catch(){}catch(){}

try{}catch(){}catch(){}finally{}

try{}finally{}

4.10 异常的练习 (应用)

  • 需求

    键盘录入学生的姓名和年龄,其中年龄为18 - 25岁,

    超出这个范围是异常数据不能赋值.需要重新录入,一直录到正确为止。

  • 实现步骤

    1. 创建学生对象。
    2. 键盘录入姓名和年龄,并赋值给学生对象。
    3. 如果是非法数据就再次录入。while
  • 代码实现

    学生类

    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 >= 18 && age <= 25){
                this.age = age;
            }else{
                //当年龄不合法时,产生一个异常
                throw new RuntimeException("年龄超出了范围");
            }
        }
    
        @Override
        public String toString() {
            return "Student{" +
                    "name='" + name + '\'' +
                    ", age=" + age +
                    '}';
        }
    }
    

    测试类

    public class ExceptionDemo12 {
        public static void main(String[] args) {
            // 键盘录入学生的姓名和年龄,其中年龄为 18 - 25岁,
            // 超出这个范围是异常数据不能赋值.需要重新录入,一直录到正确为止。
    
            Student s = new Student();
    
            Scanner sc = new Scanner(System.in);
            System.out.println("请输入姓名");
            String name = sc.nextLine();
            s.setName(name);
           while(true){
               System.out.println("请输入年龄");
               String ageStr = sc.nextLine();
               try {
                   int age = Integer.parseInt(ageStr);
                   s.setAge(age);
                   break;
               } catch (NumberFormatException e) {
                   System.out.println("请输入一个整数");
                   continue;
               } catch (AgeOutOfBoundsException e) {
                   System.out.println(e.toString());
                   System.out.println("请输入一个符合范围的年龄");
                   continue;
               }
               /*if(age >= 18 && age <=25){
                   s.setAge(age);
                   break;
               }else{
                   System.out.println("请输入符合要求的年龄");
                   continue;
               }*/
           }
            System.out.println(s);
    
        }
    }
    

4.11 自定义异常(应用)

  • 自定义异常概述

    当Java中提供的异常不能满足我们的需求时,我们可以自定义异常

  • 实现步骤

    1. 定义异常类
    2. 写继承关系
    3. 提供空参构造
    4. 提供带参构造
  • 代码实现

    异常类

    /**
     * 自定义异常
     */
    //1. 继承RuntimeException
    public class AgeOutOfBoundsException extends RuntimeException {
    //    2. 重写构造器
        public AgeOutOfBoundsException() {
        }
        public AgeOutOfBoundsException(String message) {
          super(message);
        }
    }
    

    学生类

    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 >= 18 && age <= 25){
                this.age = age;
            }else{
                //如果Java中提供的异常不能满足我们的需求,我们可以使用自定义的异常
                throw new AgeOutOfBoundsException("年龄超出了范围");
            }
        }
    
        @Override
        public String toString() {
            return "Student{" +
                    "name='" + name + '\'' +
                    ", age=" + age +
                  '}';
        }
    }
    

    测试类

    /**
     * 键盘录入学生的姓名和年龄,其中年龄为18 - 25岁,
     *
     * 超出这个范围是异常数据不能赋值.需要重新录入,一直录到正确为止。
     */
    public class Demo1 {
        public static void main(String[] args) {
            //定义一个学生对象
            Student s = new Student();
            //定义一个键盘录入对象
            Scanner sc = new Scanner(System.in);
            //
            System.out.println("请输入一个姓名:");
            String name = sc.nextLine();
            s.setName(name);
    
            while (true){
                try {
                    System.out.println("请输入一个年龄:");
                    String age_ = sc.nextLine();
                    int age = Integer.parseInt(age_);
                    s.setAge(age);
                    break;//出口
                } catch (NumberFormatException e) {
                    System.out.println("年龄输入格式不对 case:"+e.getMessage());
                }
    //            catch (RuntimeException e){
    //                System.out.println(e.getMessage());
    //            }
                catch (AgeOutOfBoundsException e){
                    System.out.println(e.getMessage());
                }
            }
            System.out.println(s);
        }
    }
    

每日总结

  1. 日期

    1. Date 构造方法、setTime getTime
    2. SimpleDateFormat
      1. String ->Date
      2. Date ->String
  2. 数组的高级操作

    1. 二分法(理解)
    2. 冒泡排序(理解)
    3. Arrays 数组工具类
  3. 递归思想

    1. 方法自己调用自己
    2. 前提:必须要有出口,没有出口就会内存溢出。
    3. 先一层一层进去,触底反弹,一层一层计算!
  4. 异常

    1. 概念:

    2. 异常分类:

      1. 在这里插入图片描述

      2. 异常处理

        1. 声明异常 throws
        2. 主动抛出异常 throw
        3. 处理异常 try{}catch(){}
        4. finally - 最终保底处理方案

能力目标

随堂案例写一下

  1. 二分法查找算法

  2. 冒泡排序

  3. Arrays-API练习

  4. 递归法求出10的阶乘

  5. 归并排序(理解)

  6. 日期转换练习

    1. 把当前日期,以2022年02月02日 12时12分12秒格式,输出到控制台.
    2. 把2022年02月02日 12时12分12秒 格式字符串,转换为Date对象.
    3. 把当前日期,以2022/02/02 12:12:12秒格式,输出到控制台.
    4. 把2022/02/02 格式字符串,转换为Date对象.
  7. 异常年龄小练习

  8. 转账异常练习

  9. 步骤:

    • 自定义余额不足异常类
    • 定义用户类、转账工具类(工具类中完成钱的减少和增加操作)
    • 写demo测试
      • 定义张三 李四 张三给李四转账。测试张三余额不足情况。
  • 7
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值