java入门(异常)

异常

概念

异常:程序中不正常的表现,会导致程序中断执行。

异常就是一个对象,当JVM检测发现由异常对象时,JVM就会中断执行。

异常体系介绍【框架】

在这里插入图片描述
【Error代码演示】

/*
    Java中的Error
    OutOfMemoryError 内存溢出错误
 */
public class Demo01 {
    public static void main(String[] args) {
        int[] arr1 = new int[4];//至少需要16Byte
        System.out.println("arr1 = " + arr1);//[I@58ceff1
        //OutOfMemoryError
        int[] arr2 = new int[Integer.MAX_VALUE];// 21亿 x4  84亿多字节
        System.out.println("arr2 = " + arr2);
    }
}
当产生异常时一般的操作方式

如果不知道异常类型,可以将异常类型拷贝到API文档中,查看具体说明。
在这里插入图片描述
在这里插入图片描述

异常的分类【Exception的分类】

在这里插入图片描述

异常产生的过程认识

在这里插入图片描述

异常处理关键字的认识
  1. throw: 异常产生的关键字,方法内部
  2. throws:用在方法声明中,表示将本方法内部的异常甩锅给方法调用处。
  3. try-catch:方法内部进行对异常进行处理
  4. inallyfinally一定要和try-catch联合使用,表示最终一定会执行的代码块。
异常的产生:throw

格式:

throw 异常对象;

【代码实践】

public class Demo01 {
    public static void main(String[] args) {
       // String hello = Objects.requireNonNull(null);

        requireNonNull(null);

        int[] arr = {10, 20, 30};
        printArray(arr, 5);

    }


    /*
   打印指定索引的数组元素
 */
    public static void printArray(int[] arr, int index) {

        if (index < 0 || index >= arr.length) {
            //非法索引
            throw new ArrayIndexOutOfBoundsException("你的索引非法哦!!"); //运行时异常   产生一个越界异常对象
        }


        int e = arr[index];

        System.out.println(e);

        System.out.println("Hello World2");

    }

    public static void requireNonNull(Object object) {
        if (object == null) {
            //空指针异常: NullPointerException
            throw new NullPointerException("老铁,你的对象空了");  //产生一个空指针异常对象
        }
    }


}
异常处理方式:throws

throws:在方法中声明,本方法中有那些异常

这是一种处理方式,如果方法中真的发生了异常,将会把异常甩锅给方法调用处。

【格式】

修饰符 返回值类型 方法名(参数列表) throws 异常1,异常2 {
  
}

【代码实践】

/*
编译时异常:编译阶段,一定要做处理

IOException
    |--FileNotFoundException

ParseException

 */
public class Demo02 {
    public static void main(String[] args) throws FileNotFoundException,ParseException {

        //String book = findBook("Java入门到精通.txt");
        String book = findBook("九阴真经.txt");

        System.out.println("book = " + book);


        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Date parse = sdf.parse("2010年10-10");
        System.out.println("parse = " + parse);


    }


    public static String findBook(String bookName) throws FileNotFoundException{
        ArrayList<String> books = new ArrayList<>();
        Collections.addAll(books, "葵花宝典.txt", "九阴真经.txt", "九阳神功.txt", "C从入门到放弃.txt");

        if (!books.contains(bookName)) {
            throw new FileNotFoundException("没有你需要的书:" + bookName); // 产生了一个编译时异常
        }

        System.out.println("恭喜找到了您的书......");

        return bookName;

    }
}
异常处理方式:try-catch
使用格式:
   try{
        可能有异常的代码:
        调用了有异常的方法;【常用】
        自己throw了编译时异常;【不常见】
   }catch(异常类型 变量){
        这个变量就是捕获的异常对象
   }

【代码实践】

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

        try {
            //String book = findBook("Java入门到精通.txt");
            String book = findBook("九阴真经.txt"); //FileNotFoundException
            System.out.println("book = " + book);
        } catch (FileNotFoundException e) {
            e.printStackTrace();//打印异常信息
        }


        try {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

            Date parse = sdf.parse("2010年10-10");

            System.out.println("parse = " + parse);

        } catch (ParseException e) {

            e.printStackTrace();

        }

        System.out.println("Hello World!!!!!!!!!!");


    }


    public static String findBook(String bookName) throws FileNotFoundException{
        ArrayList<String> books = new ArrayList<>();
        Collections.addAll(books, "葵花宝典.txt", "九阴真经.txt", "九阳神功.txt", "C从入门到放弃.txt");

        if (!books.contains(bookName)) {
            throw new FileNotFoundException("没有你需要的书:" + bookName); // 产生了一个编译时异常
        }

        System.out.println("恭喜找到了您的书......");

        return bookName;

    }


}
执行流程:

在这里插入图片描述

try-catch一次性处理多个异常

格式:

  try{
        可能有异常的代码:
        调用了有异常的方法;【常用】
        自己throw了编译时异常;【不常见】
   }catch(异常类型 变量){
        这个变量就是捕获的异常对象
   }catch(异常类型 变量){
        这个变量就是捕获的异常对象
   }catch(异常类型 变量){
        这个变量就是捕获的异常对象
   }catch(异常类型 变量){
        这个变量就是捕获的异常对象
   }

如果有存在父子类异常,若要单独处理,子类异常要放在父类异常前面
若不想单独处理子类异常,可以不写子类异常,父类异常可以直接处理子类异常

【代码实践】

/*
异常处理时,父类异常可以接受子类异常

当try-catch处理多个异常时,需要多个catch语句抓捕指定异常
如果有存在父子类异常,若要单独处理,子类异常要放在父类异常前面
若不想单独处理子类异常,可以不写子类异常,父类异常可以直接处理子类异常

 */
public class Demo01 {
    public static void main(String[] args) {
        try {
            test("文件异常");
            test("IO异常");
            test("日期解析异常");
        } catch (FileNotFoundException e) {
            String message = e.getMessage();
            System.out.println("message = " + message);
        } catch (IOException e) {
            String message = e.getMessage();
            System.out.println("message = " + message);
        } catch (ParseException e) {
            String message = e.getMessage();
            System.out.println("message = " + message);
        }

       //父类异常可以处理子类异常
        try {
            test("文件异常");
            test("IO异常");
            test("日期解析异常");
        } catch (Exception e) {
            String message = e.getMessage();
            System.out.println("message = " + message);
        }


        System.out.println("Hello World.....");
    }


    public static void test(String str) throws FileNotFoundException, IOException, ParseException {

        if (str.equals("文件异常")) {
            throw new FileNotFoundException("文件未找到异常");
        }

        if (str.equals("IO异常")) {
            throw new IOException("IO异常");
        }

        if (str.equals("日期解析异常")) {
            throw new ParseException("日期异常", 100);
        }

    }


}
关键字finally的使用:

finallytry-catch结合一起使用,表示一定要执行的代码。

格式

try{
  
}catch(){
  
}finally{
  //一定要执行的代码块
}

使用场景:IO流使用中,资源的关闭动作,可以放到finally代码块中。

【代码实践】

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

        String name = goToLibrary();
        System.out.println("name = " + name);
    }


    public static String goToLibrary() {
        String book=null;
        try {
             book = findBook("葵花宝典.txt");

            //System.out.println("找书结束");
            return book;  //葵花宝典.txt
        } catch (FileNotFoundException e) {
            String message = e.getMessage();
            System.out.println("message = " + message);
            return null;
        }finally {
            //保证一定执行,即使真正发生了异常
            System.out.println("找书结束");
            return "《" + book + "》"; //《葵花宝典.txt》
        }

    }



    public static String findBook(String bookName) throws FileNotFoundException {
        ArrayList<String> books = new ArrayList<>();
        Collections.addAll(books, "葵花宝典.txt", "九阴真经.txt", "九阳神功.txt", "C从入门到放弃.txt");

        if (!books.contains(bookName)) {
            throw new FileNotFoundException("没有你需要的书:" + bookName); // 产生了一个编译时异常
        }

        System.out.println("恭喜找到了您的书......");

        return bookName;

    }


}
try-catch处理异常的说明

当一个异常在该方法产生时,思考是否自己可以处理,【自己处理是否有意义】,如果有意义可以使用try-catch,如果自己处理没有任何意义,使用throws甩锅处理让方法调用者去处理。

异常处理时注意事项:

  1. 运行时异常被抛出可以不处理。即不捕获也不声明抛出。

  2. 如果父类抛出了多个异常,子类覆盖父类方法时,只能抛出相同的异常或者是他的子集。

  3. 父类方法没有抛出异常,子类覆盖父类该方法时也不可抛出异常。此时子类产生该异常,只能捕获处理,不能声明抛出

  4. 当多异常处理时,捕获处理,前边的类不能是后边类的父类

  5. 在try/catch后可以追加finally代码块,其中的代码一定会被执行,通常用于资源回收。

  6. 多个异常使用捕获又该如何处理呢?

    多个异常分别处理。

    1. 多个异常,多次处理。
    2. 多个异常一次捕获一次处理。【父类异常处理子类异常】
自定义异常类型
  1. 为什么要自定义异常类?

    JDK中提供了很多异常,当逻辑中要使用的异常类型JDK没有提供时,就可以自己去定义异常。

  2. 如何自定义异常类?

    定义一个子类继承异常类型

    public class 类型 extends 异常类型{ }
    
  3. 异常有编译时异常Exception,有运行时异常RuntimeException,该如何选择?

    编译时异常:要求使用的人强制处理,处理后能够保证程序正常执行

    运行时异常:不要求强制处理,但是一旦报错,程序崩溃。

    优先选择编译时异常,应该要继承Exception

  4. 练习巩固

    模拟用户注册账号,如果账号已存在,异常报错

    因为JDK中不存在一个账号注册异常,需要自己动手创建一个异常类

自定义异常类型:

/*
自定义注册异常
 */
public class RegisterException extends Exception { //编译时异常
    public RegisterException() {
    }

    public RegisterException(String message) {
        super(message);
    }
}

自定义异常的使用,与JDK中的异常一样。

public class Demo01 {
    public static void main(String[] args)  {
        try {
            boolean result = register("迪丽热巴123", "123123");
        } catch (RegisterException e) { //处理捕获的是自己定义的异常
           // e.printStackTrace();
            String message = e.getMessage();
            System.out.println("注册失败:" + message);
        }

    }


    public static boolean register(String username, String password) throws RegisterException {
        ArrayList<String> account = new ArrayList<>();
        Collections.addAll(account, "迪丽热巴", "古力娜扎", "abc", "aaaa");

        if (!account.contains(username)) {
            account.add(username);
            System.out.println("注册成功!!");
            return true;
        }

        throw new RegisterException("不好意思!!用户名已被占用"); //抛出了一个自定义的编译时异常

    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值