zoukankan      html  css  js  c++  java
  • Java基础之:异常及异常处理

    Java基础之:异常及异常处理

    我们将java程序执行过程中出现的不正常现象称为异常,例如:之前遇到的数组下标越界异常,空指针异常等等

    执行过程中发生的异常事件分为两类:

    Error(错误):Java虚拟机无法解决的严重问题,如:JVM系统内部错误,资源耗尽等严重情况。比如:StackOverFlowError(栈溢出),Error是严重错误,程序会直接崩溃掉。

    Exception:其他因为编程错误或偶然的外在因素导致的一般性问题,可以使用针对性的代码进行处理。例如空指针访问等。Exception分为两大类:运行时异常(在程序运行过程中)、编译时异常(在程序编译过程中)

     

     

    常见的运行时异常

    NullPointerException:空指针异常
    public class NullPointerException_ {
        private static String str;
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            System.out.println(str.length());
            System.out.println("hello~");
        }
    ​
    }
    

     

    ArithmeticException:数学运算异常

    当出现异常的运算条件时,抛出此异常。例如,一个整数“除以零”时,抛出此类的一个实例, 例如:int i = 10 / 0

     

    ArrayIndexOutOfBoundsException:数组下标越界异常
    public class ArrayIndexOutOfBoundsException_ {
    ​
        public static void main(String[] args) {
    ​
            int[] arr = {1,2};
            System.out.println(arr[4]);
    }
    

      

    ClassCastException:类型转换异常

    当试图将对象强制转换为不是实例的子类时,抛出该异常。例如,以下代码将生成一个 ClassCastException

    public class ClassCastException_ {
    ​
        public static void main(String[] args) {
            
            Animal a = new Dog();
            Cat cat = (Cat)a;
        }
    ​
    }
    ​
    ​
    class Animal {
        
    }
    class Dog extends Animal {
        
    }
    class Cat extends Animal {
        
    }
     
    NumberFormatException:数字格式不正确异常

    当应用程序试图将字符串转换成一种数值类型,但该字符串不能转换为适当格式时,抛出该异常 => 使用异常我们可以确保输入是满足条件数字.

    public class NumberFormatException_ {
        public static void main(String[] args) {
            String name = "小范~";
            int num = Integer.parseInt(name);
        }
    }
    

    常见的编译时异常

    1. SQLException //操作数据库时,查询表可能发生异常

    2. IOException //操作文件时,发生的异常

    3. FileNotFoundException //当操作一个不存在的文件时,发生异常

    4. ClassNotFoundException //加载类,而该类不存在时,异常

    5. EOFException // 操作文件,到文件末尾,发生异常

    6. IllegalArguementException //参数异常

     

    异常处理

    异常处理就是当异常发生时,对异常处理的方式。

    两种方式:

    1. try-catch-finally

      程序员在代码中捕获异常,并自行处理

    2. throws

      将发生的异常抛出给调用方,最顶级的调用方就是JVM

     

    try-catch异常处理

    Java提供try和catch块来处理异常。try块用于包含可能出错的代码。catch块用于处理try块中发生的异常。可以根据需要在程序中有任意数量的try...catch块。

    基本语法:

    try{

      //可能出现异常的代码

      //将异常生成对应的异常对象,作为参数传递给catch

    }catch(异常对象){

      //异常处理

    }

    public class Exception_ {
    ​
        public static void main(String[] args) {
            String a = null;
            try {
                System.out.println(a.length());
                System.out.println(a);
            } catch (Exception e) {
                // TODO: handle exception
                System.out.println(e.getMessage());
            }
        }
    }

    注意事项

    如果异常发生了,则异常发生那条语句后面的代码不会执行,直接进入catch块

    如果异常没有发生,正常执行try块,不会进入catch块

    可以使用多个catch块,捕获不同的异常(进行不同的业务处理),要求父类异常在后面,子类异常在前面。例如: RuntimeException在后面,NullPointerException在前面。如果发生异常只会匹配一个catch。

     

    try-catch-finally异常处理

    相较于try-catch而言,多了一个finally块,它的作用是:不管有没有出现异常,都一定会执行finally块中的代码。

    当然也可以使用try-finally,但这种方法和不处理异常是一样的,最后会让JVM机来处理异常。而JVM机处理异常的方式,就是直接输出异常信息然后终止程序。所以不建议这样使用。

    try-catch-finally案例

    public class try_catch_finally{
        public static void main(String args[]){
            int[] a = {1,2,3};
            try{
                System.out.println(a[4]);
            }catch{
                System.out.println("数组下标越界异常");
            }finally{
                System.out.println("finally块执行....");
            }
        }
    }

    程序输出:

    数组下标越界异常

    finally块执行....

     

    练习题

    考虑下面程序输出:

    package class_exception;
    ​
    public class Test {
    ​
        @SuppressWarnings("finally")
        public static int method() {
            try {
                String[] names = new String[3];
                if (names[1].equals("john")) {// 空指针异常
                    System.out.println(names[1]);
                } else {
                    names[3] = "lucy";
                }
                return 1;
            } catch (ArrayIndexOutOfBoundsException e) {
                return 2;
            } catch (NullPointerException e) {
                return 3;
            } finally { // 一定要执行
                return 4;
            }
        }
    ​
        public static void main(String[] args) {
            System.out.println(method());
        }
    }

    练习题2

    考虑程序输出:

    package class_exception;
    ​
    public class Test {
    ​
        public static int method() {
            int i = 1;
            try {
                i++; // 2
                String[] names = new String[3];
                if (names[1].equals("john")) { // 空指针异常
                    System.out.println(names[1]);
                } else {
                    names[3] = "lucy";
                }
                return 1;
            } catch (ArrayIndexOutOfBoundsException e) {
                return 2;
            } catch (NullPointerException e) {
                return ++i;     //提示:不是立即返回 记录 i= i+1 = 3 保存到 temp = 3
            } finally {
                ++i; 
                System.out.println("i=" + i);
            }
        }
    ​
        public static void main(String[] args) {
            System.out.println(method());   
        }
    }
    

      

    应用案例

    如果用户输入的不是一个正整数,就提示他反复输入,直到输入一个正整数为止

    import java.util.Scanner;
    ​
    public class ClassWork {
    ​
        @SuppressWarnings("resource")
        public static void main(String[] args) {
            Scanner input = new Scanner(System.in);
            int age;
            System.out.println("输入年龄:");
            for(;;) {
                try {
                    age = new Scanner(System.in).nextInt();
                    break;
                } catch (Exception e) {
                    System.out.println("再次输入年龄(正整数):");
                    continue;
                }
            }
            
            System.out.println("END");
        }
    }

     

    throws异常处理

    如果一个方法(中的语句执行时)可能生成某种异常,但是并不能确定如何处理这种异常,则此方法应声明抛出异常,表明该方法将不对这些异常进行处理,而由该方法的调用者负责处理。

    在方法声明中用throws语句可以声明抛出异常的列表,throws后面的异常类型可以是方法中产生的异常类型,也可以是它的父类。

    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    public class Throws01 {
        public static void main(String[] args) throws FileNotFoundException {
    ​
            // 1. 使用try
            // 2. 使用throws
            
            m1();
            System.out.println("ok");
        }
        public static void m1() throws FileNotFoundException {
            FileInputStream fis = new FileInputStream("d://aa.txt");// 编译异常
        }
    }

    使用细节:

    1. 对于编译异常,程序中必须处理,使用try-catch或throws

    2. 对于运行时异常,程序如果没有处理,默认就是throws方式处理,将其抛给最顶层调用方JVM

    3. 子类重写父类的方法时,对抛出异常的规定:子类重写的方法,所抛出的异常类型要么和父类抛出的异常一致,要么为父类抛出的异常的类型的子类型

    4. 在throws 过程中,如果有方法 try-catch , 就相当于处理异常,就可以不必throws

    细节3案例:

    class Father {
        public void m1() throws RuntimeException{
            
        }
    }
    ​
    class Son extends Father{
        @Override
        public void m1() throws NullPointerException{
            
        }
    }

     

    自定义异常

    1. 定义类:自定义异常类名(程序员自己写) 继承Exception或RuntimeException

    2. 如果继承Exception,属于编译异常

    3. 如果继承RuntimeException,属于运行异常(一般来说,继承RuntimeException)

    自定义异常应用案例

    package class_exception.ClassCustomException;
    import java.util.Scanner;
    ​
    /**
     * 当我们接收Person对象年龄时,要求范围在 1 – 130 之间,否则抛出一个自定义异常(要求 继承自定义异常)
     */
    public class ClassWork01 {
    ​
        public static void main(String[] args) {
            Scanner scanner = new Scanner(System.in);
            Person p = new Person();
            
            System.out.println("请输入年龄:");
            for(;;) {
                
                try {
                    int a = scanner.nextInt();
                    p.setAge(a);
                    break;
                } catch (Exception e) {
                    // TODO: handle exception
                    System.out.println(e.getMessage());
                    System.out.println("请重新输入年龄:");
                    continue;
                }
                
            }
        }
    }
    ​
    class Person{
        private int age;
    ​
        public Person(int age) {
            this.age = age;
        }
        
        public Person() {
        }
    ​
        //创建方法使用异常
        public void setAge(int a) throws AException{
            if(!(a>=0 && a<=130)) {
                throw new AException("异常 要求范围在 1 – 130 之间");
            }
        }
    }
    ​
    class AException extends RuntimeException{
        /**
         * 添加版本号,不用管
         */
        private static final long serialVersionUID = 1L;
    ​
        //使用构造器传入异常信息
        public AException(String name){
            super(name);
        }
    }

     

    自定义异常应用案例2

    package class_exception.ClassCustomException;
    import java.util.Scanner;
    /**
     * 编写应用程序,接收一个数,要求不能输入负数,进行异常处理。要求使用继承 RuntimeException 来实现,
     */
    public class ClassWork02 {
        public static void main(String[] args) {
            
            Scanner s = new Scanner(System.in);
            System.out.println("输入一个数:");
            try {
                int a = s.nextInt();
                //因为是运行时异常,也可以不使用try处理
                if(a<0) {
                    throw new IntException("不能输入负数");
                }
            }catch(RuntimeException e){
                System.out.println("异常信息:" + e.getMessage());
            }
            
            System.out.println("END");
        }
    }
    ​
    class IntException extends RuntimeException{
        private static final long serialVersionUID = 1L;
        public IntException(String name) {
            super(name);
        }
    }

     

    throw 和 throws 的区别

     

  • 相关阅读:
    红旗桌面版本最新行使方法和效果解答100例4
    红旗桌面版本最新运用行为和标题问题解答100例3
    红旗桌面版本最新运用方式和成效解答100例2
    Linux下Resin JSP MySQL的部署和设置配备铺排2
    在Linux下Turbomail简易快捷的装置体式格局
    企业级Linux红旗桌面版可以可能登岸日本
    从红旗5.0说起——看Linux的内存管理
    红旗Linux桌面4.1文本布置过程图解(一)
    Linux下Resin JSP MySQL的装置和设置装备安排1
    Ubuntu 8.04中竖立Apache PHP MySQL基本环境
  • 原文地址:https://www.cnblogs.com/SongHai/p/14154059.html
Copyright © 2011-2022 走看看