欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

第五章 异常处理

程序员文章站 2024-03-02 23:05:16
...

Java程序设计第五章 异常处理

1.异常的概述与异常的体系结构

  • 外部原因导致程序异常:比如客户输入数据格式,读取文件是否存在,网络是否始终保持通畅。

  • 异常:在Java语言中,将程序执行中发生的不正常的情况称之为异常,但是开发过程中语法错误和逻辑错误不是异常

    • Error:java虚拟机无法解决的严重问题。JVM系统内部错误、资源耗尽严重情况。

      public class ErrorDemo01 {
          public static void main(String[] args) {
      //        栈溢出java.lang.*Error
                main(args);
          }
      }
      
    • Exception:其他因编程错误或偶然的外在因素导致的一般性问题,可以使用针对性的代码进行处理,例如空指针访问,试图读取不存在的文件,网络连接中断,数据下标越界等等

    • 出现错误通常表明出现了异常,但是出现异常却比一定出现了错误

    • 异常的分类
      第五章 异常处理

2.常见的异常举例

  • 空指针异常 NullPointException

    public class ExceptionDemo01 {
        public static void test1(){
            int[] arr = null;
            System.out.println(arr[3]);
        }
        public static void main(String[] args) {
            test1();
        }
    }
    
    public class ExceptionDemo01 {
        public static void test2(){
            String str = "abc";
            str = null;
    //        charAt(0)寻找该字符串的第0个字符
            System.out.println(str.charAt(0));
        }
        public static void main(String[] args) {
            test2();
        }
    }
    
  • 数组角标越界 java.lang.ArrayIndexOutOfBoundsException

    public class ExceptionDemo01 {
        public static void test3() {
            int[] arr = new int[3];
            System.out.println(arr[3]);
        }
        public static void main(String[] args) {
            test3();
        }
    }
    
  • 类型转换异常java.lang.ClassCastException

    import java.util.Date;
    
    public class ExceptionDemo01 {
        public static void test4() {
            Object obj = new Date();
            String str = (String)obj;
        }
        public static void main(String[] args) {
            test4();
        }
    }
    
  • 数字格式异常java.lang.NumberFormatException

    public class ExceptionDemo01 {
        public static void test5() {
            String str = "abc";
            int num = Integer.parseInt(str);
        }
        public static void main(String[] args) {
            test5();
        }
    }
    
  • 输入不匹配异常java.util.InputMismatchException

    import java.util.Scanner;
    
    public class ExceptionDemo01 {
        public static void test6() {
            Scanner scanner = new Scanner(System.in);
            int score = scanner.nextInt();
    //        比如输入一个字符串就会出现该异常
            System.out.println(score);
        }
        public static void main(String[] args) {
            test6();
        }
    }
    
  • 算数异常java.lang.ArithmeticException

    public class ExceptionDemo01 {
        public static void test7() {
            int a = 10;
            int b = 0;
            System.out.println(a/b);
        }
        public static void main(String[] args) {
            test7();
        }
    }
    
  • 编译型异常举例

    import java.io.File;
    import java.io.FileInputStream;
    import java.io.IOException;
    //如果没有抛出IOExceotion出现编译型异常不会生成java字节码文件
    public class ExceptionDemo02 {
       public void test1() throws IOException {
          File file = new File("hello.txt");
          FileInputStream fis = new FileInputStream(file);
          int data = fis.read();
          while (data !=-1){
             System.out.println((char)data);
             data = fis.read();
          }
          fis.close();
       }
    }
    

3.异常处理机制一:try-catch-finally

异常处理抓抛模型

  • “抛”,程序在正常执行的过程中,一旦出现异常,就会在异常代码中生成一个对应异常类对象,并将此对象抛出,一旦抛出对象以后,其后代码就不会执行

  • “抓”,可以理解为异常的处理方式,try-catch-finally,throws

    try{
       //可能出现异常的代码
    }catch(异常类型1,变量名1){
        //处理异常的方式一
    }catch(异常类型2,变量名2){
        //处理异常的方式二
    }catch(异常类型3,变量名3){
        //处理异常的方式三
    }
    ···
    finally{
       //一定会执行的代码
    }
    
  • try-catch举例

    //finally是可选的
    //使用try将可能出现异常的代码包装起来,在其执行过程中,一旦出现异常,就会生成对应异常类的对象,根据此对象的类型,在catch中进行匹配
    //一旦try中的对象匹配到一个catch时我们就进入catch中进行处理,一旦处理完成就跳出当前try-catch结构
    //在try结构中声明的变量,在出了try结构以后,就不能在被调用
    //try - catch结构处理编译时异常,使得程序在编译时就不再报错,但是运行时仍可能报错
    //try - catch结构根据需要可以嵌套
    public class ExceptionDemo03 {
       public static void test1(){
           String str = "123";
           str =  "abc";
    //       将num定义到try结构的外面即可
           int num =0 ;
           try{
               num =  Integer.parseInt(str);
               System.out.println("hello..........1");
           }catch (NullPointerException e){
               System.out.println("出现空指针异常,不要着急......");
           }catch (NumberFormatException e){
               //           输出异常两种方式
               System.out.println("出现数值转换异常,不要着急.....");
               System.out.println(e.getMessage());
    //           包含getmessagehai而且还会显示那些结构出现问题
               e.printStackTrace();
           }catch (Exception e){
               System.out.println("出现异常,不要急......");
           }
           System.out.println(num);
           System.out.println("hello................2");
       }
    
        public static void main(String[] args) {
            test1();
        }
    }
    
  • finally的使用

    public class FinallyDemo01 {
    //    finally声明的是一定会被执行的代码,即使try或者catch中有return语句也会执行
        public static void test1(){
            try{
                int a = 10;
                int b = 0;
                System.out.println(a/b);
            }catch (AbstractMethodError e){
                e.printStackTrace();
            }catch (Exception e){
                e.printStackTrace();
            }finally {
                System.out.println("hello");
            }
        }
    
        public static void main(String[] args) {
            test1();
        }
    }
    

    像数据库连接,输入输出流,网络编程的Socket等资源,JVM是不是自动回收,需要自己手动的资源释放,资源的释放操作就需要声明到finally使其一定被释放

    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.IOException;
    
    public class FinallyDemo02 {
    //   IO流的异常处理操作
        public static void test2(){
            FileInputStream fis = null;
            try {
                File file = new File("hello.txt");
                fis = new FileInputStream(file);
                int data = fis.read();
                while (data != -1){
                    System.out.println((char)data);
                    data = fis.read();
                }
            }catch (FileNotFoundException e){
                e.printStackTrace();
            }catch (IOException e){
                e.printStackTrace();
            }finally {
    //            如果没有这个判断语句将会出现空指针异常
                if (fis != null){
    //            自己本身也可能出异常
                    try {
                        fis.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    
        public static void main(String[] args) {
            test2();
        }
    }
    
  • 实际开发过程中运行时异常比较常见,通常就不针对运行时异常编写try-catch,因为你捕获异常之后也不能解决问题,直接改代码,但是编译型异常一定要用try-catch。

4.异常处理机制二:throws

  • try-catch-finally是真正将异常处理掉,但是throws方式只是将异常抛给了方法的调用者,并没有处理异常

    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.IOException;
    // throws+异常类型处理方式,写在方法的声明处,指明此方法执行时,可能会出现的异常类型
    //try-catch才是处理异常,throws只是甩锅不能解决异常,异常代码后续的代码就不会执行
    public class ThrowsDemo01 {
    //    main方法需要自己处理,把异常处理掉,不然jvm会出现问题
        public static void main (String[]args) throws IOException {
            try{
                method2();
            }catch (FileNotFoundException e){
                e.printStackTrace();
            }catch (IOException e){
                e.printStackTrace();
            }
        }
    //    方法二往main方法甩锅
        public static void method2() throws FileNotFoundException,IOException {
             method1();
        }
    //  方法一往上面甩锅
        public static void method1() throws FileNotFoundException, IOException {
            FileInputStream fis = null;
            File file = new File("hello.txt");
            fis = new FileInputStream(file);
            int data = fis.read();
            while (data != -1) {
                System.out.println((char) data);
                data = fis.read();
            }
            fis.close();
            System.out.println("hello.......");
        }
    }
    
  • 子类重写方法抛出的异常不大于父类被重写方法抛出的异常类型

  • 如果父类被重写的方法没有throws方式处理异常,则子类重写的方法也不能用throws,只能用try-catch-finally抛出异常

  • 执行的方法中先后调用了另外几个方法,这几个方法是递进关系则使用throws方法处理,而执行方法用try-catch-finally处理异常

5.手动抛出异常:throw

  • 产生异常的两种方式:一是系统自动生成的异常,二是手动生成异常,并抛出(throw)

    public class ThrowStudentText {
        public static void main(String[] args)  {
            Student s = new Student();
    //      处理异常
            try {
                s.regist(-1);
                System.out.println(s);
            } catch (Exception e) {
                System.out.println(e.getMessage());
            }
        }
    }
    class Student {
        private int id;
    //    将手动抛出的异常处理上抛给main方法处理
        public void regist(int id) throws Exception{
            if (id>0){
                this.id = id ;
            }else{
    //            手动抛出编译时异常
                throw new Exception("您输入的数据非法!");
            }
        }
    }
    
    

6.用户自定义异常类

  • 用户自定义异常都是直接继承RuntimeException、Exception

    class MyExceptionDemo01 {
        public static void main(String[] args) throws MyException {
            execute("java");
        }
    
        public static void execute(String a) throws MyException {
            System.out.println("execute.......");
            if ("java".equals(a)){
                throw new MyException("参数不能为java");
            }
        }
    //    自定义异常类继承Exception
        public static class MyException extends Exception{
    //     提供重载的构造器   
            public MyException(){
                super();
            }
            public MyException(String msg){
    //     还原父类的调用
                super(msg);
            }
        }
    }
    
相关标签: java exception