java异常体系

一、异常体系图

1、Error程序无法处理的系统错误,编译器不做检查。一般与jvm相关,系统崩溃,虚拟机错误,内存空间不足。

2、Exception程序可以处理的异常,捕获后可能恢复。

  RuntimeException:不可预知的,程序应当自行避免。

  非RuntimeException:可预知,从编译器检查异常。

从责任看:

1、Error属于JVM需要负担的责任。

2、RuntimeException是程序应该负担的责任。

3、Checked Exception是java编译器应该负担的责任。

在使用编译器编写代码时,非RuntimeException是需要在程序中被处理的,使用try-catch或throws抛出。

而RuntimeException异常,即使不做处理,代码同样可以编译通过。这就需要在代码中预测可能出现的异常,提前处理。

二、常见的Error和Exception异常

RuntimeException:

1、NullPointException 空指针引用异常

2、ClassCastException 类型强制转换异常

3、IllegalArgumentException 传递非法参数异常

4、IndexOutOfBoundsException 下标越界异常

5、NumberFormatException 数字格式异常

非RuntimeException:

1、ClassNotFoundException 找不到指定class的异常

2、IOException IO操作异常

Error:

1、NOClassDefFoundError 找不到class定义的异常

2、StackOverflowException 深递归导致栈被耗尽而抛出的异常

3、OutOfMemoryError 内存溢出异常

三、异常捕获处理

1、throws抛出

import java.io.FileInputStream;
import java.io.FileNotFoundException;

public class ExceptionTest {
    public static void main(String[] args) throws FileNotFoundException {
        test();

    }
    
    static void test() throws FileNotFoundException {
        FileInputStream fis = new FileInputStream("");
    }
}

一层层抛出,交给系统处理。

2、try-catch

只处理异常信息,不抛出异常,程序不会终止

import java.io.FileInputStream;
import java.io.FileNotFoundException;

public class ExceptionTest {
    public static void main(String[] args) throws FileNotFoundException {
        test();

    }

    static void test() {
        try {
            FileInputStream fis = new FileInputStream("");
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }
}

处理异常信息,同时抛出RuntimeException异常,程序终止

import java.io.FileInputStream;
import java.io.FileNotFoundException;

public class ExceptionTest {
    public static void main(String[] args) throws FileNotFoundException {
        test();

    }

    static void test() {
        try {
            FileInputStream fis = new FileInputStream("");
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            throw new RuntimeException();
        }
    }
}

异常处理原则:

具体明确:抛出的异常应能通过异常名和message信息准确说明异常的类型和产生异常的原因。

提早抛出:应尽可能早的发现并抛出异常,便于精确定位。

延迟捕获:异常捕获和处理应尽可能延迟,让掌握更多信息的作用域来处理异常。将异常使用throws子句抛出给它的调用者,让调用者来明确异常信心。

四、注意事项

1、finally关键字,在return语句或throw之前执行,经常用于关闭io流。

2、自定义业务异常,继承RuntimeException。catch块中抛出的同样是RuntimeException异常。因为抛出非RuntimeException异常就需要再次try-catch。

 3、异常处理会消耗性能,在某些情况下,可食用if检查来代替。消耗性能的原因:1、try-catch影响jvm的优化、2、异常对象实例需要保存栈快照等信息,消耗较大。

如下测试:

    static void testIf(String[] array){
        if(array != null){
            System.out.println(array[0]);
        } else{
            System.out.println("array is null");
        }
    }

    static void testException(String[] array){
        try{
            System.out.println(array[0]);
        }catch (NullPointerException e){
            System.out.println("arrays is null");
        }
    }

测试if性能:

   @Test
    public void testIf(){
        long start = System.nanoTime();//纳秒
        testIf(null);
        System.out.println(System.nanoTime() - start +"ns!");
    }

结果(连续3次):

array is null
153000ns!

array is null
124900ns!

array is null
126100ns!

测试try-catch性能:

    @Test
    public void testException(){
        long start = System.nanoTime();//纳秒
        testException(null);
        System.out.println(System.nanoTime() - start +"ns!");
    }

结果(连续3次):

arrays is null
263800ns!

arrays is null
212100ns!

arrays is null
203000ns!

结果显示:try-catch使用之后性能消耗较大。

就算这个世道烂成一堆粪坑,那也不是你吃屎的理由
原文地址:https://www.cnblogs.com/whalesea/p/12932846.html