Skip to content

day05 【API、异常】

今日内容介绍

java
Math类
BigInteger类
BigDecimal类
基本类型包装类
异常

第一章 Math 类

1.1 Math 类的介绍【重点学会怎么找到并使用】

java
/*
    java.lang.Math类: 用于数学运算的工具类
    特点:
        1.成员都使用static修饰
        2.构造方法private修饰
    静态成员:
        public static final double PI: 常量,代表圆周率
        public static int abs(int a): 返回参数的绝对值
        public static double ceil(double a): 返回大于或等于参数的最小double值,等于一个整数
        public static double floor(double a): 返回小于或等于参数的最大double值,等于一个整数
        public static int round(float a): 按照四舍五入返回最接近参数的int
        public static double pow(double a, double b): 计算a的b次方

    注意:
        以上方法中必须掌握ceil方法
*/

1.2 Math 类的使用【重点】

java
package com.itheima.demo;

public class MathDemo {

    public static void main(String[] args) {
        /**
         * Math类 是数学类
         *    里面封装了跟数学运算相关的方法。
         *    也就是说如果我们程序中遇到了一些数学运算,那么我们可以直接调用Math的功能即可,就不需要我们人为的是实现了。
         *
         *    这种类在实际开发应用场景在哪里呢?
         *          比如:
         *             计算商品的时候,如果给商品打折比如88折,得到的结果可能是不是有好多位数,需要四舍五入。
         *             猿辅导教育---初中生数学辅导,习题,计算三角函数的--调用方法计算出来。
         */
        /**
         * public static int abs(int a)              计算绝对值
         * public static double ceil(double a)       向上取整
         * public static double floor(double a)      向下取整
         * public static int round(float a)          四舍五入
         */
        System.out.println(Math.abs(-100));//100
        System.out.println(Math.abs(100));//100
        //向上取整   --找到大于等于 其的 整数值(小数形式)
        System.out.println(Math.ceil(3.14));//4.0
        System.out.println(Math.ceil(-3.14));//-3.0
        //向下取整    -- 找到小于等于 其的 整数值(小数形式)
        System.out.println(Math.floor(3.14));//3
        System.out.println(Math.floor(-3.14));//-4
        // 四舍五入
        System.out.println(Math.round(3.14));// 四舍五入成整数
    }
}

第二章 BigInteger 类

2.1 大数运算介绍

java
/*
    1.基本类型整数的取值范围?
        byte	1个字节	-128到127
        short	2个字节	正负3万多
        int		4个字节	正负21亿
        long	8个字节	大概19位数字

    2.基本类型整数取值范围最大的就是long类型, 如果整数的范围超过了long类型,怎么办呢?
        解决方案: 大整数
            java.math.BigInteger类: 代表超级大的整数,不可变的任意精度的整数。

    3.基本类型小数的取值范围?
        float	4个字节
        double	8个字节

    4.基本类型小数取值范围最大的就是double类型, 如果小数的范围超过了double类型,怎么办呢?
        解决方案: 大小数
            java.math.BigDecimal类: 代表超级大的小数,不可变的、任意精度的小数。
    5.注意:
        如果数据的取值范围超出了数字的最大范围,此时这样的数字称为大数
        java.math.BigInteger类: 代表超级大的整数,不可变的任意精度的整数。
        java.math.BigDecimal类: 代表超级大的小数,不可变的、任意精度的小数。
*/

2.2 BigInteger 类的使用

大整数使用套路

  • 把数据先封装到大整数对象中
  • 跟另外一个大整数 进行加减乘除
java
/*
    BigInteger类的使用
    java.math.BigInteger类: 代表超级大的整数,不可变的任意精度的整数。
    1.构造方法:
        public BigInteger(String val):
        	作用: 把构造方法参数String类型的val,转换成BigInteger类的对象
            参数: 必须是String类型的数字,内部不能出现非数字内容

    2.常用方法:
        数学运算中最常用的就是+,-,*,/,所以对于BigInteger类提供了对应的方法
        public BigInteger add(BigInteger val):
            完成数学中的加法运算,
            返回其值为 (this(调用add方法的BigInteger对象) + val(调用add方法时传递的参数BigInteger对象)) 的 BigInteger。

        public BigInteger subtract(BigInteger val):
            完成数学中的减法运算,
            返回其值为 (this(调用add方法的BigInteger对象) - val(调用add方法时传递的参数BigInteger对象)) 的 BigInteger。

        public BigInteger multiply(BigInteger val):
            完成数学中的乘法运算,
            返回其值为 (this(调用add方法的BigInteger对象) * val(调用add方法时传递的参数BigInteger对象)) 的 BigInteger。

        public BigInteger divide(BigInteger val):
            完成数学中的除法运算,
            返回其值为 (this(调用add方法的BigInteger对象) / val(调用add方法时传递的参数BigInteger对象)) 的 BigInteger。
*/
java
package com.itheima.math01;

import java.math.BigInteger;

public class BigIntegerDemo {

    public static void main(String[] args) {
        // 大整数的使用  表示任意长度的 整数  不受个数限制
//        int i1 = 2222222222;
//        int i2 = 1123444422;
//        System.out.println(i1+i2);
        //构造  BigInteger(String value)
        BigInteger a = new BigInteger("2222222222");
        BigInteger b = new BigInteger("1111111111");
        //大整数怎么计算
        //调用方法
        System.out.println("a+b:"+a.add(b));
        System.out.println("a-b:"+a.subtract(b));
        System.out.println("a*b:"+a.multiply(b));
        System.out.println("a/b:"+a.divide(b));
    }
}

2.3 浮点数的不精确性

java
/*
    使用double完成加减乘除运算

    问题: 出现损失精度的问题

    不允许: 钱的问题

    解决方案: 使用java.math.BigDecimal类

 */
public class Demo04DoubleProblem {
    public static void main(String[] args) {
        double d1 = 0.03;
        double d2 = 0.02;
        System.out.println(d1 + d2);
        System.out.println(d1 - d2);
        System.out.println(d1 * d2);
        System.out.println(d1 / d2);
    }
}

第三章 BigDecimal 类 银行要用

3.1 BigDecimal 类的介绍

java
/*
    BigInteger类的使用
    java.math.BigDecimal类: 代表超级大的小数,不可变的任意精度的小数。
    1.构造方法:
        public BigDecimal(String val):
        	作用: 把构造方法参数String类型的val,转换成BigDecimal类的对象
            参数: 必须是String类型的数字,内部不能出现非数字内容

    2.常用方法:
        数学运算中最常用的就是+,-,*,/,所以对于BigDecimal类提供了对应的方法
        对于+,-,*这些运算和BigInteger是一样的,就不再演示了
        但是对于 除法 运算,可能会出现 无限循环/无限不循环的结果
        然而BigDecimal是用来完成超级精确的数学运算,这样就导致
        BigDecimal不知道到底给你什么样的结果?
        解决方案:
            (1)告诉它保留多少位小数
            (2)如何保留小数

        public BigDecimal divide(BigDecimal divisor, int scale, int roundingMode):
            按照方法参数指定的保留位数以及保留方式做除法运算
            参数:
                 int scale: 要保留几位小数
                 int roundingMode: 如何保留小数
                        BigDecimal.ROUND_UP 向上加1。
                        BigDecimal.ROUND_DOWN 直接舍去。
                        BigDecimal.ROUND_HALF_UP 四舍五入。
*/

3.2 BigDecimal 类的使用

java
package com.itheima.math01;

import java.math.BigDecimal;

public class BigDecimalDemo {

    public static void main(String[] args) {
        // BigDecimal(String value) 封装一个大小数对象
        BigDecimal a = new BigDecimal("0.03");
        BigDecimal b = new BigDecimal("0.02");
        //加减乘除
        System.out.println("a+b:"+a.add(b));
        System.out.println("a-b:"+a.subtract(b));
        System.out.println("a*b:"+a.multiply(b));
        System.out.println("a/b:"+a.divide(b));

        //除会除不尽 情况  出现了异常
        BigDecimal d = new BigDecimal("1.0");
        BigDecimal e = new BigDecimal("3.0");
        /*
        1.BigDecimal.ROUND_UP  向上加1。
        2.BigDecimal.ROUND_DOWN 直接舍去。
        3.BigDecimal.ROUND_HALF_UP 四舍五入
         */
        System.out.println("d/e:"+d.divide(e,2,BigDecimal.ROUND_UP));//向上加一
        System.out.println("d/e:"+d.divide(e,2,BigDecimal.ROUND_DOWN));//直接舍去
        System.out.println("d/e:"+d.divide(e,2,BigDecimal.ROUND_HALF_UP));//四舍五入
    }
}

第四章 基本类型包装类【重点】

4.1 包装类的概念

java
/*
    包装类的概念
    ArrayList集合存储基本类型数据时,要求<>中必须指定基本类型对应的引用类型(包装类)

        基本类型                引用类型(包装类)
        byte                    Byte
        short                   Short
        int                     Integer
        long                    Long
        float                   Float
        double                  Double
        char                    Character
        boolean                 Boolean

    集合中永远只能存储引用类型:
        只需要在创建集合对象时,<>中指定对应的包装类,其它操作都可以按照基本类型完成

    引用类型(包装类)并不是对基本类型的简单替换,而是包装类中提供了大量的方法完成相关功能
*/
java
package com.itheima.baozhuang;

import java.util.ArrayList;

public class BaoZhuangDemo {
    public static void main(String[] args) {
//        ArrayList<引用类型>   类 接口
          // int 不是引用类型
//        ArrayList<int> arrayList = new ArrayList<int>();泛型类型不能是基本类型
        ArrayList<Integer> arrayList = new ArrayList<>();//采用包装类型去做

        arrayList.add(11);//方法上要的参数  对象Integer类型  你写的是 数值
        arrayList.add(12);//方法上要的参数  对象Integer类型  你写的是 数值
        arrayList.add(13);//方法上要的参数  对象Integer类型  你写的是 数值
                            // 其实存的并不是int值 而是一个Integer对象
                           // 直不过 我们jvm编译期 帮你 完成了 int--Integer的转换
                                                             //  int--Integer的转换  这种转换称为装箱
                                                              //基本类型 包装成了 对应的包装类对象  装箱
        Integer num = arrayList.get(1);

        int n = num;// 这里是 包装类型对象 转换成了 基本类型  这个操作称为拆箱
    }
}

4.2 Integer 类对象的创建【重点】

java
/*
    java.lang.Integer类对象的创建
    Integer 类在对象中包装了一个基本类型 int 的值。
    构造方法:
        public Integer(int value):
            把构造方法int参数value,转换成Integer对象

        public Integer(String value):
            把构造方法String参数value,转换成Integer对象

    注意:
        1.构造方法参数不可以超出int的范围
        2.构造方法如果采用String的参数,参数中不可以包含非数字字符
*/
java
package com.itheima.baozhuang;

public class BaoZhuangDemo2 {

    public static void main(String[] args) {
        // int数据 123 转换成 Integer对象
//        Integer i = 123;//自动的装箱
       Integer i = new Integer(123);//把数值 123 包装成 包装类Integer类型
        System.out.println(i.toString());
       Integer ii = new Integer("123");//把字符串中的 数字字符串 包装成Integer类型
        System.out.println(ii.toString());
        //建议
        Integer iii = 123;//体现了自动装箱

        Double  dou = 1.1;
        Double d = new Double(1.1);

    }
}

4.3 装箱 和 拆箱的概念

java
基本类型和对应包装类之间存在相互转换,装换的过程,称为"装箱""拆箱"

**装箱:**从基本类型转换为对应的包装类型。

**拆箱:**包装类型转换成基本类型。

装箱方法:

java
1:构造 new Integer(int i)
2:通过静态方法 static Integer valueOf(int i)

拆箱方法: (对象)参数引用类型,返回值是基本类型

java
int	intValue()
将 Integer的值作为 int
这个方法是一个普通方法,需要Integer对象调用。
   public static void main(String[] args) {
        // 基本类型--引用类型
        Integer integer = Integer.valueOf(10);
        // 引用类型对象 转换成 基本类型
        int i = integer.intValue();

        System.out.println(i);

    }

4.4 包装类的自动装箱拆箱

java
/*
    包装类的自动装箱拆箱
    自动装箱:
        基本类型数据,可以自动转换为对应的引用类型(包装类),是自动完成滴,不需要代码特殊处理

    自动拆箱:
        引用类型数据(包装类),可以自动转换为对应的基本类型,是自动完成滴,不需要代码特殊处理
*/
java
// 自动拆装箱  也就是说 我们的写法变得简单了!!
        // 写代码的方式可以变得简单  -- 这种简单的写法 JDK1.5之后进行优化的!
        // 这是叫自动装箱和拆箱   你编译期代码可以简写  但是生成的.class文件底层 实际上还是上面的方式。
        Integer integer1 = 10;//底层 Integer.valueOf(10);---明天老师讲一个面试题。

        int i1 = integer1;//底层 integer.intValue();
java
ArrayList<Integer> list = new ArrayList<Integer>();
list.add(1);//有装箱  int类型 包装Integer类型

Integer i = 4;// 自动装箱  把4 包装成了一个 Integer对象
i = i+5;// 做加法的时候 先完成了拆箱 i 拆成了int 类型 4 + 5 = 9 9是int
        //赋值的时候 完成了装箱

4.5 基本类型转换成对应的字符串 只掌握第一个

java
方式一 +空字符串
方式二 通过包装类     static String	toString(int i)
方式三  通过String中的一个静态方法  static String	valueOf(int i)
java
       //int ---String
        int a = 10;
        //方式一
        String s = a+"";
        //方式二 通过包装类 int参数---String返回值
        /*
        static String	toString(int i)返回一个 String指定整数的 String对象。
         */
        String ss = Integer.toString(a);
        //方式三  通过String中的一个静态方法  static String	valueOf(int i)
        String sss = String.valueOf(a);

4.6 String 解析成对应的基本类型 重要

java
/*
    String解析成对应的基本类型(很常用的)
        包装类中除了Character以外,每个包装类都会提供一个静态方法
            public static xxx parseXxx(String str):
                把方法参数String数据str转换成xxx类型的数据

        Integer类:
            public static int parseInt(String str):
                把方法参数String数据str转换成int类型的数据

        Double类:
            public static double parseDouble(String str):
                把方法参数String数据str转换成double类型的数据

        Boolean类:
            public static boolean parseBoolean(String str):
                把方法参数String数据str转换成boolean类型的数据
*/
java
public class Demo07ParseString {
    public static void main(String[] args) {
        String str = "20";

        //把String数据转换成int数据
        int num = Integer.parseInt(str);
        System.out.println(num);//20
        System.out.println(num + 20);//40
        System.out.println("---------------");

        String str2 = "66.66";
        //把String数据转换成double数据
        double num2 = Double.parseDouble(str2);
        System.out.println(num2);//66.66
        System.out.println(num2 + 33.33);//99.99
        System.out.println("---------------");

        String str3 = "true";
        boolean reslut = Boolean.parseBoolean(str3);
        System.out.println(reslut);//true
        System.out.println(!reslut);//false
    }
}

第五章 异常【重点】

5.0 异常引入

异常:就是不正常,在程序执行过程中,出现了非正常的情况,最终导致了 JVM 非正常的结束。

NullPointException ClassNoCastException.

在 java 中,异常本身是一个类,在产生异常的位置,创建一个异常对象并抛出。默认的处理方式就是抛出给 JVM,JVM 中止程序。比如我们见到过索引越界异常。

java
public class ExceptionDemo01 {

    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<>();

        list.add("贾乃亮");
        list.add("陈羽凡");
        list.add("王宝强");

        System.out.println(list.get(3));

        System.out.println("这些人不容易~!");
    }
}

1640858778314

1640858793795

1640858808706

5.1 异常的概念和体系

java
/*
    异常:程序中的意外问题,处理异常,提供一种预防机制(预案),写字楼中的消防栓
    异常的体系:
        |--Object
            |--Throwable 程序中可能会出现的所有的不正常的情况
                |--Error 程序中的致命的问题,严重的错误
                    比如:绝症 一旦出现了Error,程序不能继续进行
                |--Exception(编译时期的异常) 程序中的小的问题,小的错误,
                    比如:感冒,发烧,阑尾炎 只要将问题处理了,程序可以继续运行
    异常和错误的区别
        异常: 感冒 发烧 阑尾炎 可以处理 处理之后代码可以继续执行
        错误: 癌症晚期 艾滋 非典 不能处理

        名称:
            错误: XxxError
            异常: XxxException
*/

5.2 异常的分类【了解】

java
/*
    异常的分类
        |-- 编译时期异常:checked异常(受检测异常)。
            在编译时期,就会检查,如果没有处理异常,则编译失败。(如日期格式化异常)
            直接继承Exception

        |-- 运行时期异常:runtime异常。
            在运行时期,检查异常.
            在编译时期,运行异常编译器不会检测(不报错)。(如数学异常)
            不影响编译,可以正常生成.class文件,但是运行时期可能会出现问题
            直接继承RuntimeException
*/
java
public class Demo01Exception {
    public static void main(String[] args) throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String strDate = "2020-09-24";
        /*
            parse方法内部声明抛出ParseException异常,
            ParseException异常直接继承Exception,
            说明是编译时期异常,在编译阶段必须处理(目前用throws处理),
            不处理编译报错
         */
        Date date = sdf.parse(strDate);
        System.out.println(date);

        System.out.println("-----------");
        int[] array = {10, 20, 30};
        /*
            运行时期会报出索引越界异常:ArrayIndexOutOfBoundsException
            ArrayIndexOutOfBoundsException继承RuntimeException,是
            运行时期异常,不会影响编译,会产生.class文件,只不过在运行时期,
            可能会产生这种问题
         */
        int value = array[5];

        System.out.println(value);
    }
}

5.3 异常中常用的方法

Throwable--它里面的方法 所有的子类都有

java
   printStackTrace(); 打印异常的详细信息
   包含了异常的类型,异常的原因,异常出现的位置。----开发阶段如果我们想要异常信息就用这个方法。

1640916683594

java
String getMessage() 获取异常的描述信息(原因)

1640858883048

java
String  toString() 把异常信息转换成字符串  出现了异常的类型和原因。

1640858891125

5.4 异常的产生和 JVM 处理异常的方式【重要】

java
/*
    JVM默认的异常处理机制
        1.打印异常信息
        2.停止程序的执行(全都得死)
 */
public class Demo02Exception {
    public static void main(String[] args) {
        int[] array = {100, 200, 300};
        int value = getValue(array, 5);
        System.out.println("main方法中正确获取到数组元素值: " + value);
    }

    public static int getValue(int[] array, int index) {
        int value = array[index];
        System.out.println("getValue方法中正确获取到数组元素值: " + value);
        return value;
    }
}

1600931895028

第六章 异常处理

6.1 throw 的用法【重要】

java
/*
    Demo02Exception中异常对象是由JVM创建并自动抛出的
        如果我们想自己创建异常对象并手动抛出
        需要使用throw关键字
        throw关键字: 扔,抛的意思
        throw关键字使用格式:
            throw 异常对象;
            throw new 异常类(...);
        注意:
            1.throw必须使用在方法内部
            2.throw后面必须写异常对象,而且只能写一个
            3.throw表示把一个具体的异常对象抛出给该方法的调用者
*/
java
public class Demo03ExceptionThrow {
    public static void main(String[] args) {
        int[] array = {100, 200, 300};
        //array = null;
        int value = getValue(array, 5);

        System.out.println("main方法中正确获取到数组元素值: " + value);
    }

    public static int getValue(int[] array, int index) {
        //如果数组是null,抛出空指针异常
        if (array == null) {
            throw new NullPointerException("数组array是null了,不能获取元素了?");
        }
        //如果索引越界,抛出索引越界异常
        if (index < 0 || index >= array.length) {
            throw new ArrayIndexOutOfBoundsException("数组索引越界了: "+index);
        }
        int value = array[index];
        System.out.println("getValue方法中正确获取到数组元素值: " + value);
        return value;
    }
}

6.2 throws 声明抛出异常【重要】

java
/*
    异常处理方式一:
    使用throws关键字: 声明抛出异常
        告诉方法的调用者,你调用我的方法时,我方法内部有可能会产生什么样子的异常,
        方法内部没有处理,谁调用我谁来处理
    使用格式:
        修饰符 返回值类型 方法名称(形式参数列表....) throws 异常类 {
            方法体;
        }
    场景:
        项目经理:   JVM
        项目组长:   main方法
        程序猿:     sports方法
    注意:
        1.throws关键字必须写在方法声明的后面
        2.throws关键字后面跟的是异常类,而且可以写多个
        3.throw必须使用在方法内部
        4.throw后面必须写异常对象,而且只能写一个
        5.throw表示把一个具体的异常对象抛出给该方法的调用者
*/
java
public class Demo04ExceptionThrows {
    public static void main(String[] args) throws Exception {
        System.out.println("组长安排程序员跑圈开始....");
        sports(5);
        System.out.println("组长安排程序员跑圈结束....");
    }
    //模拟程序猿锻炼身体: 跑圈
    public static void sports(int num) throws Exception {
        System.out.println("已经跑了3圈....");
        if (num > 3) {
            throw new Exception("心脏病发作....");
        }
    }
}

6.3 throws 声明抛出多个异常【了解】

java
/*
    异常处理方式一:
        使用throws关键字: 声明抛出多个异常
        告诉方法的调用者,你调用我的方法时,我方法内部有可能会产生什么样子的异常,
        方法内部没有处理,谁调用我谁来处理
        使用格式:
            修饰符 返回值类型 方法名称(形式参数列表....) throws 异常类1,异常类2 {
                方法体;
            }
        场景:
            项目经理:   JVM
            项目组长:   main方法
            程序猿:     sports方法
 */
public class Demo05ExceptionThrows {
    public static void main(String[] args) throws ParseException,FileNotFoundException  {
        System.out.println("开始读取文件内容...");
        readFile(3);
        System.out.println("结束读取文件内容...");
    }

    //模拟读取文件内容的方法
    public static void readFile(int num) throws ParseException,FileNotFoundException {
        if (num == 1) {
            throw new ParseException("解析文件失败",num);
        }
        if (num == 2) {
            throw new FileNotFoundException("文件不存在");
        }
        System.out.println("文件内容: 好好学习天天向上....");
    }
}

6.4 try-catch 处理异常【重要】

try-catch 我们其实也可以对异常,尝试着进行抓取处理!

这种处理方式叫捕获异常

捕获的格式:

java
try{
   就是可能出现异常的代码;
}catch(异常类型 e){
    你在这里可以对e进行判刑
}

它的出现 就替代了 throws 也就是我进行了捕获,说明我自己要试着处理了,就不麻烦别人了,就不用声明了。

java
package com.itheima.exceptionhandler;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.text.ParseException;

public class TryCatchDemo3 {
    /**
     try...catch 处理手法
     尝试 抓取 异常
     格式
     try{
     可能出现异常的代码;
     }catch(异常类型 e){//这个异常类型用于接收抓取到异常对象

     //你可以进行自己的任何处理  想怎么处理就怎么处理
     }
     替代了 throws
     */
    public static void main(String[] args) {
        System.out.println("开始解析文件");

        try {
            readFile(2);//试着 抓取 这里出现的异常
        } catch (FileNotFoundException e) {//抓 FileNotFoundException这个异常
            e.printStackTrace();//抓到异常之后的默认处理方式 打印异常详细信息
            System.exit(0);//进行程序的停止
            //给程序员发短信
        }


        System.out.println("解析文件完成");
    }
    //模拟读取文件内容的方法
    public static void readFile(int num) throws FileNotFoundException {

        if (num == 2) {
            throw new FileNotFoundException("文件不存在");
        }


        System.out.println("文件内容: 好好学习天天向上....");
    }
}

6.5 try-catch 处理异常流程【了解】

1627460291246

6.6 多 catch 处理异常【了解】

多个异常怎么处理 多个 catch , 需要如果有子父类关系,先处理子类再出父类。

建议我们直接写父类,就不用写子类了。你还可以直接写上级父类 Exception

java
package com.itheima.exceptionhandler;

import java.io.FileNotFoundException;
import java.io.IOException;

public class TryCatchDemo4 {
    /**
     try...catch 如何抓取多个异常
        根据提示出来的处理方式 叫做 多catch处理方式
       注意
       最好 就使用父类异常 抓取
         如果写了父类异常 还有子类异常 注意 子类异常要在上面
     */
    public static void main(String[] args)  {
        System.out.println("开始解析文件");


        try {
            findFile("D:");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }catch (IOException e) {
            e.printStackTrace();
        }

        System.out.println("解析文件完成");
    }
    public static void findFile(String path) throws ClassNotFoundException,FileNotFoundException, IOException {

        if(path.contains("D:")){//如果盘符是D盘 就找不到文件

            //怎么抛出异常
            throw  new FileNotFoundException("您访问的盘符都不存在,更别说文件了。");

        }else if(path.contains(".txt")){//这种文件形式 在读取文件的时候会出现异常  IOException

            //抛出一个IOException
            throw  new IOException("您的文件在读取的时候出现了异常");
        }else{
            System.out.println("可以找到文件");
            throw  new ClassNotFoundException("类找不到异常");
        }
    }
}
java
package com.itheima.exceptionhandler;

import java.io.FileNotFoundException;
import java.io.IOException;

public class TryCatchDemo5 {
    /**
     try...catch 如何抓取多个异常
        根据提示出来的处理方式 叫做 多catch处理方式
       注意
       最好 就使用父类异常 抓取
         如果写了父类异常 还有子类异常 注意 子类异常要在上面
        最简单的方式 直接抓取最大的父类异常 Exception
     */
    public static void main(String[] args)  {
        System.out.println("开始解析文件");


        try {
            findFile("D:");
        } catch (Exception e) {
            e.printStackTrace();
        }

        System.out.println("解析文件完成");
    }
    public static void findFile(String path) throws ClassNotFoundException,FileNotFoundException, IOException {

        if(path.contains("D:")){//如果盘符是D盘 就找不到文件

            //怎么抛出异常
            throw  new FileNotFoundException("您访问的盘符都不存在,更别说文件了。");

        }else if(path.contains(".txt")){//这种文件形式 在读取文件的时候会出现异常  IOException

            //抛出一个IOException
            throw  new IOException("您的文件在读取的时候出现了异常");
        }else{
            System.out.println("可以找到文件");
            throw  new ClassNotFoundException("类找不到异常");
        }
    }
}

6.7 try-catch-finally 的使用【重要】

finally 代码块:

​ 作用:在程序运行的时候,有些代码是不管程序是否有异常,一定要运行的。

对于这种代码,我只需要方法 finally 代码块中,就可以实现。

使用场景:用在 IO 流的释放中。

java
package com.itheima.exceptionhandler;

import java.io.IOException;

public class FinallyDemo {
    public static void main(String[] args) {

        try {
            show();
            System.out.println("没有问题 执行这句话");
        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("执行到这里 就出现了问题");
            System.out.println("出现问题我让方法停止");
            return;
        }finally {
            System.out.println("不管有没有异常 我都会执行");
        }

        System.out.println("我是over代码 结束代码");

    }

    public static void show () throws IOException{

        throw  new IOException("我是故意写出来的异常");
    }
}

6.8 编译时期异常和运行时期异常的区别【重要】

java
异常:就是程序不正常了。可能就是我们代码或者代码相关的内容出现问题,我们应该发现问题,解决问题。

​          从而再减少问题。

在java中,把问题封装成了异常类。

Throwable

|---Error  错误,一般是非代码类问题,比如内存不够用了,内存溢出。

|---Exception  一般是代码类问题,平常说的异常。

|---编译期异常,可能出现问题的位置会在编译期提示。

​                     特点: 一旦调用的功能中抛出过编译异常,就需要我们进行解决。

​                      解决方案:

​                               throws声明,一个是try-catch捕获。

​                     一般来说 我们见到的编译期异常都是,我们操作跟外界因素有点关系,

​                     出了问题两方面思考,代码问题,一个是外界问题。

​                        io异常、文件找不到异常、类型解析异常、类文件找不到异常。

|---非编译期异常,编译阶段不会有异常的提示。

​                    也可以使用  throws声明,一个是try-catch捕获。

​                     因为解决操作有默认的机制,JVM进行的处理。

​                     一般的问题就是代码不够严谨,有漏洞,俗称bug。你需要好好看发生的位置原因,进行解决。

throw关键字 抛出 在方法中使用。

throws 将异常声明出去,告知别人我这里有异常。

捕获 进行代码的监控,出现了异常就进行捕获抓取,进行对应的处理。

finally关键字 不是一定要用的,它有它的场景:有些代码,不管你程序如何,必须执行的就使用finally代码块。

6.10 异常后方法重写注意事项【了解】

java
运行期异常被抛出可以不处理(不声明,不捕获),因为JVM默认有解决方案。
1:如果父类方法抛出了异常,子类的方法如果重写可以不抛出异常,如果要抛那么就要和父类保持一致或者是父类异常子类。
2:父类如果没有异常,子类重写的方法就不能抛!
3:多异常catch处理的时候,子类要在父类前面。
4:throws可以直接声明大的异常,小的异常就不用声明。

父类中的方法抛了异常,那么子类重写之后要不要抛?
    父类中的方法没有抛异常,那么子类重写之后要不要抛
java
//父类
public class Fu {
    public void method() {
        System.out.println("Fu...method....");
    }
}

//子类
public class Zi extends Fu {
    /*
        父类method方法声明上,没有使用throws声明抛出异常
        子类重写后的方法,内部有异常,不能使用throws
        只能内部try-catch处理  ---使用场景: 在讲多线程(day09/day10)的时候会用到
     */
    @Override
    public void method()/* throws Exception*/ {
        System.out.println("Zi...method...");
        try {
            throw new Exception("子类重写后出问题了!!!!");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

第七章 自定义异常【重要】

7.1 自定义异常简单演示

java
/*
    自定义异常
        虽然jdk中提供了大量的异常类,但是和我们实际的业务开发场景无关
        所以我们需要根据需求自定义异常类
    步骤:
        1.自定义类继承Exception(编译时期异常)或者RuntimeException(运行时期异常)
            继承谁都可以,没有统一规定
        2.根据父类生成空参/满参构造
        3.代码中就可以使用throw关键字抛出异常对象
 */
public class Demo12MyException {
    public static void main(String[] args) {
        try {
            show();
        } catch (UserNameRegisterException e) {
            e.printStackTrace();
        }
    }

    public static void show() throws UserNameRegisterException {
        throw new UserNameRegisterException("用户名已经被注册了");
    }
}
java
//自定义编译时期异常: 用户名已经被注册的异常类
public class UserNameRegisterException extends Exception {
    //空参构造
    public UserNameRegisterException() {
    }

    //满参构造
    public UserNameRegisterException(String message) {
        super(message);
    }
}

7.2 自定义异常练习

java
/*
    自定义异常练习
        模拟注册操作,如果用户名已存在,则抛出异常并提示:亲,该用户名已经被注册。
    实现步骤:
        1.创建ArrayList集合list,存储数据类型String,模拟已经注册的用户
        2.向ArrayList集合list添加多个字符串,代表已经注册的用户
        3.定义方法判断新的用户名是否可以用
        4.创建键盘录入对象
        5.获取键盘录入的新的用户名,保存到String变量userName中
        6.调用步骤3中定义的方法,判断新的用户名是否可用
*/
java
public class Demo13ExceptionTest {
    public static void main(String[] args) {
        //1.创建ArrayList集合list,存储数据类型String,模拟已经注册的用户
        ArrayList<String> list = new ArrayList<>();

        //2.向ArrayList集合list添加多个字符串,代表已经注册的用户
        list.add("jack");
        list.add("rose");
        list.add("lucy");
        list.add("lili");
        list.add("hanmeimei");
        list.add("lilei");

        //4.创建键盘录入对象
        Scanner sc = new Scanner(System.in);

        //5.获取键盘录入的新的用户名,保存到String变量userName中
        System.out.println("请输入您要注册的用户名: ");
        String userName = sc.nextLine();

        //6.调用步骤3中定义的方法,判断新的用户名是否可用
        /*
            checkUserName方法声明抛出了一个编译时期异常,必须处理
            要么throws,要么try-catch
            此处建议使用try-catch
            原因: 这里可能是一个比较大的网站,不能因为注册用户失败,而影响用户使用其它功能
            所以: 使用try-catch把这个问题处理掉,程序可以继续向下执行(用户可以继续完成除了注册以外的其它功能)
         */
        try {
            checkUserName(list,userName);
        } catch (UserNameRegisterException e) {
            e.printStackTrace();
        }

        System.out.println("看看其它图片....");
        System.out.println("看看其它视频....");
    }

    //3.定义方法判断新的用户名是否可以用
    public static void checkUserName(ArrayList<String> list, String userName) throws UserNameRegisterException {
        //遍历集合
        for (int i = 0; i < list.size(); i++) {
            if (list.get(i).equals(userName)) {
                /*
                    抛出编译时期异常,必须处理
                    要么throws,要么try-catch
                    此处建议使用throws,由调用者来处理此异常
                    因为: 一旦抛出此异常,说明用户名已经被注册,检测用户名是否被注册的这个方法的功能代码
                    没有必要继续执行了
                 */
                throw new UserNameRegisterException("非常抱歉用户名: "+userName+" 已经被注册...");
            }
        }

        //执行到这里
        System.out.println("恭喜您,用户名: "+userName+" 可以使用...");
    }
}

Released under the MIT License.