zoukankan      html  css  js  c++  java
  • 错误处理

    1. 常见异常

    异常都是从Throwable类派生出来的,而Throwable类是直接从Object类继承而来。

    通常的异常有四类: 
    1. Error : 系统内部错误,这类错误由系统进行处理,程序本身无需捕获处理。 
    2. Exception:可以处理的异常 
    3. RuntimeException:可以捕获,也可以不捕获的异常 
    4. 继承Exception的其他类:必须捕获,通常在API文档会说明这些方法抛出哪些异常。

    2. 算术异常

    J2SE官方API文档 - ArithmeticException 
    Java SE官方文档对于算术异常的定义是:

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

    public class AriExceptionTest {
        public static void main(String[] args) {
            System.out.println("Example 1:  -1.0 / 0 = " + (-1.0 / 0));
            // 演示负浮点数除0
    
            System.out.println("Example 2:  +1.0 / 0 = " + (+1.0 / 0));
            // 演示正浮点数除0
    
            System.out.println("Example 3:  -1 / 0 = " + (-1 / 0));
            // 演示负整数除0
    
            System.out.println("Example 4:  +1 / 0 = " + (+1 / 0));
            // 演示正整数除0
        }
    }
    Example 1:  -1.0 / 0 = -Infinity
    Example 2:  +1.0 / 0 = Infinity
    Exception in thread "main" java.lang.ArithmeticException: / by zero
        at 算术异常.AriExceptionTest.main(AriExceptionTest.java:11)
    Example 1:  -1.0 / 0 = -Infinity
    Example 2:  +1.0 / 0 = Infinity
    Exception in thread "main" java.lang.ArithmeticException: / by zero
        at 算术异常.AriExceptionTest.main(AriExceptionTest.java:11)

    看到,实际上程序在运行到Example 3的时候就已经出现了算数异常。当代码抛出一个异常的同时,也终止了对剩余代码的处理,所以Example 4根本没有机会执行。

    那么Example 1和2中为什么能出现结果呢?

    这是由于在Java中,浮点数(无论是float还是double类型的浮点数)被0除,并不会引发算术异常。具体说来,是操作系统为了保护应用软件而已经处理了该异常,不再抛出,最终运算结果是无穷大。

    3. 数组下标越界异常

    J2SE官方API文档 - ArrayIndexOutOfBoundsException 
    Java SE官方文档对于数组下标越界异常的定义是:

    用非法索引访问数组时抛出的异常。如果索引为负或大于等于数组大小,则该索引为非法索引。

    import java.util.Arrays;
    
    public class ArrayExceptionTest {
    
        public static void main(String[] args) {
            int[] array = new int[5]; 
            // 声明一个长度为5的整型数组array
    
            Arrays.fill(array, 8); 
            // 将该数组所有元素赋值为8
    
            for (int i = 0; i < 6; i++) {
                // 用遍历的方式,输出所有数组元素,注意此处的控制条件 i < 6
    
                System.out.println("array[" + i + "] = " + array[i]);
                //下标将会增加到5,显然是超出了数组array的范围(0到4),程序将在第6次循环前抛出异常
            }
        }
    }
    array[0] = 8
    array[1] = 8
    array[2] = 8
    array[3] = 8
    array[4] = 8
    Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 5
        at 算术异常.ArrayExceptionTest.main(ArrayExceptionTest.java:17)
    array[0] = 8
    array[1] = 8
    array[2] = 8
    array[3] = 8
    array[4] = 8
    Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 5
        at 算术异常.ArrayExceptionTest.main(ArrayExceptionTest.java:17)

    4. 空指针异常

    J2SE官方API文档 - NullPointerException 
    Java SE官方文档对于空指针异常的定义是:

    当应用程序试图在需要对象的地方使用 null 时,抛出该异常。这种情况包括: 
    1. 调用 null 对象的实例方法。 
    2. 访问或修改 null 对象的字段 
    3. 将 null 作为一个数组,获得其长度。 
    4. 将 null 作为一个数组,访问或修改其时间片。 
    5. 将 null 作为 Throwable 值抛出。 
    应用程序应该抛出该类的实例,指示其他对 null 对象的非法使用。

    public class NullPointerExceptionTest {
    
        public static void main(String[] args) {
            String s= null;
            // 将字符串设置为null
    
            System.out.println(s.toUpperCase());
            // 尝试将字符串转换成大写,看看会发生什么
        }
    
    }
    Exception in thread "main" java.lang.NullPointerException
        at 算术异常.NullPointerExceptionTest.main(NullPointerExceptionTest.java:9)

    5. 自定义异常类

    尽管Java SE的API已经为我们提供了数十种异常类,然而在实际的开发过程中,你仍然可能遇到未知的异常情况。此时,你就需要对异常类进行自定义。

    自定义一个异常类非常简单,只需要让它继承Exception或其子类就行。在自定义异常类的时候,建议同时提供无参构造方法和带字符串参数的构造方法,后者可以为你在调试时提供更加详细的信息。

    百闻不如一见,下面我们尝试自定义一个算术异常类。

    import java.util.Arrays;
    
    public class ExceptionTest {
        public static void main(String[] args) {
            int[] array = new int[5];
            //声明一个长度为5的数组
    
            Arrays.fill(array, 5);
            //将数组中的所有元素赋值为5
    
            for (int i = 4; i > -1; i--) {
                //使用for循环逆序遍历整个数组,i每次递减
    
                if (i == 0) {
                // 如果i除以了0,就使用带异常信息的构造方法抛出异常
    
                    throw new MyAriException("There is an exception occured.");
                }
    
                System.out.println("array[" + i + "] / " + i + " = " + array[i] / i);
                // 如果i没有除以0,就输出此结果
            }
        }
    }
    array[4] / 4 = 1
    array[3] / 3 = 1
    array[2] / 2 = 2
    array[1] / 1 = 5
    Exception in thread "main" 算术异常.MyAriException: There is an exception occured.
        at 算术异常.ExceptionTest.main(ExceptionTest.java:19)

    5. 捕获异常

    当我们在编程时遇到了异常不要紧,除了可以将异常抛出,还可以将异常捕获。通常使用try和catch语句块来捕获异常,有时候还会用到finally。

    对于上述三个关键词所构成的语句块,try语句块是必不可少的,catch和finally语句块可以根据情况选择其一或者全选。你可以把可能发生错误或出现问题的语句放到try语句块中,将异常发生后要执行的语句放到catch语句块中,而finally语句块句,不管异常是否发生,它们都会被执行。

    你可能想说,那我把所有有关的代码都放到try语句块中不就妥当了吗?可是你需,捕获异常对于系统而言,其开销非常大,所以应尽量减少该语句块中放置的语句。

    public class CatchException {
        public static void main(String[] args)
        {
            try
            {
                System.out.println("I am try block.");
                //声明一个空的Class对象用于引发“类未发现异常”
                Class<?> tempClass = Class.forName("");
    
                System.out.println("BYE! try block.");
            }catch(ClassNotFoundException e)
            {
                // 下面定义了一个catch语句块
                System.out.println("I am catch block.");
    
                e.printStackTrace();
                //printStackTrace()的意义在于在命令行打印异常信息在程序中出错的位置及原因
    
                System.out.println("Goodbye! Catch block.");
            }finally 
            {
                // 下面定义了一个finally语句块
                System.out.println("I am finally block.");
            }
    
        }
    
    }
    I am try block.
    I am catch block.
    java.lang.ClassNotFoundException: 
        at java.lang.Class.forName0(Native Method)
        at java.lang.Class.forName(Class.java:264)
        at 算术异常.CatchException.main(CatchException.java:10)
    Goodbye! Catch block.
    I am finally block
     
     
  • 相关阅读:
    LeetCode Find Duplicate File in System
    LeetCode 681. Next Closest Time
    LeetCode 678. Valid Parenthesis String
    LeetCode 616. Add Bold Tag in String
    LeetCode 639. Decode Ways II
    LeetCode 536. Construct Binary Tree from String
    LeetCode 539. Minimum Time Difference
    LeetCode 635. Design Log Storage System
    LeetCode Split Concatenated Strings
    LeetCode 696. Count Binary Substrings
  • 原文地址:https://www.cnblogs.com/gaoss/p/6628203.html
Copyright © 2011-2022 走看看