Java的异常体系

1.异常体系

  1. 几乎所有的代码都会出现异常,为了保证程序在出现异常后可以正常执行完毕,最大化的减少损失的一种保护手段。
  2. Java中异常也是类。
  3. 异常类继承关系:只有Throwable以及其子类能够进行异常捕获与处理。

![![在这里插入图片描述](https://img-blog.csdnimg.cn/20190503141400683.png](https://img-blog.csdnimg.cn/20190503141431172.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L21pX3poaV9sdQ==,size_16,color_FFFFFF,t_

  • Error: 描述JVM运行时内部错误,栈溢出,堆溢出;
  • Exception: 程序中普遍存在的,由于代码问题产生的;
    • IOException: 由于输入输出产生的异常 ,如在程序中打开一个并不存在的文件;
    • RuntimeException: 发生在运行时异常,编译时不报错。如数组越界异常,类型转换异常,空指针异常(NPE)
      受查异常:除了非受查异常的所有异常类都属于受查异常。即强制用户进行处理。
      非受查异常:Error, RuntionException及其子类。即不强制用户进行处理。

2. 异常处理

异常处理:当异常产生时,尽量保证异常之后的代码可以执行。
异常处理的三种格式:

1. try...[1...N]catch...
2. try...finally...
3. try...[1...N]catch...finally...
  • try : 所有可能出现异常的代码;
  • catch : 当相应异常出现时,捕获该异常,然后自定义处理方式;
  • finally :保证重点代码 (如:IO流的关闭,JDBC资源的释放以及网络的连接关闭)一定会执行的机制,无论是否产生异常,finally代码中的内容一定会被执行。

举例:产生异常

public class ExceptionTest {
    public static void main(String[] args) {
        System.out.println("1.数学计算前...");
        System.out.println("2.数学计算中..."+(10/0));  //运行时异常
        System.out.println("3.数学计算后...");    //不能被执行
    }
}
/**
1.数学计算前...
Exception in thread "main" java.lang.ArithmeticException: / by zero
	at www.csdn.qh.ExceptionTest.main(ExceptionTest.java:11)
*/

举例:异常处理
如果有异常出现,执行catch语句;如果没有异常,不执行catch语句

public class ExceptionTest {
    public static void main(String[] args) {
        System.out.println("1.数学计算前...");
        try {
            System.out.println("2.数学计算中..."+(10/0));
        } catch (Exception e) {
            System.out.println("异常被处理了");      
        }
        System.out.println("3.数学计算后...");
    }
}
/**
1.数学计算前...
异常被处理了
3.数学计算后...
*/

以上代码中虽然进行了异常处理,但是你根本不知道程序产生了什么异常,所以为了获取异常具体信息,可以直接输出异常类对象,或者调用异常类中提供的printStackTrace()方法进行完整异常信息的输出。
举例:输出异常信息

public class ExceptionTest {
    public static void main(String[] args) {
        System.out.println("1.数学计算前...");
        try {
            System.out.println("2.数学计算中..."+(10/0));
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("3.数学计算后...");
    }
}
/**
1.数学计算前...
java.lang.ArithmeticException: / by zero
3.数学计算后...
*/

举例:使用try...catch...finally...异常处理1
finally作为程序统一出口。

public class ExceptionTest {
    public static void main(String[] args) {
        System.out.println("1.数学计算前...");
        try {
            System.out.println("2.数学计算中..."+(10/0));
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            System.out.println("不管是否有异常,都会执行此句");
        }
        System.out.println("3.数学计算后...");
    }
}
/**
1.数学计算前...
java.lang.ArithmeticException: / by zero
不管是否有异常,都会执行此句
	at www.csdn.qh.ExceptionTest.main(ExceptionTest.java:12)
3.数学计算后...
*/

举例:使用try...catch...finally...异常处理2

public class ExceptionTest {
    public static void main(String[] args) {
        System.out.println(test());    //2
    }

    public static  int  test(){
        try {
            System.out.println(10/0);
            return 0;
        }catch (ArithmeticException e){
            return 1;
        }finally {
            return 2;
        }
    }
}

不管try中是否有异常,finally中的代码都会被执行,且优先于try和catch中的代码
举例:将JVM退出exit(),这样不会执行finally

public class Test {
    public static void main(String[] args) {
        try {
            System.out.println("1");
            //系统退出
            exit(0);
        } catch (Exception e) {
            System.out.println("2");
        } finally {
            System.out.println("3");
        }
    }
}
//1

2.1 非运行时异常(非受查异常)

*Error、RuntimeException及其子类,*不强制用户进行处理。

public class Test {
    public static void main(String[] args) {
        System.out.println("1.计算开始");
        try{
            fun();
            System.out.println("2.计算开始");
        }catch (Throwable e){  //也可以替换成Error
            e.printStackTrace();   //java.lang.StackOverflowError
        }
        System.out.println("3.计算结束");
    }

    private static void fun() {
        fun();
    }
}

2.2 受查异常

在IDE工具中,代码底下画红线,不能编译通过,必须要尽心处理。

public class TestString {
    public static void main(String[] args) {
        File file = new File("abc.txt");
        try {
            InputStream inputStream = new FileInputStream(file);
        } catch (FileNotFoundException e) {   //继承IOException
            e.printStackTrace();
        }
    }
}

3.throws

throws:用在方法声明上,明确表示该方法可能会产生异常。当产生异常时,将异常扔给调用者,谁调谁处理。

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

        try {
            System.out.println(caculate(10,0));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static int caculate(int a, int b)throws Exception {
        return a/b;
    }
}
//java.lang.ArithmeticException: / by zero

当出现异常时,方法将异常扔回给调用者,当调用者不处理时,可以继续往回扔。实际就是一个帅锅过程
举例:主方法抛出异常

public class Test {
    public static void main(String[] args) throws Exception{
        System.out.println(caculate(10,0));
    }

    private static int caculate(int a, int b)throws Exception {
        return a/b;
    }
}
//Exception in thread "main" java.lang.ArithmeticException: / by zero

4. throw

throw:用在方法中,表示人为进行异常对象的产生。一般与自定义异常类搭配使用。
举例:throw的非受查异常

public class Test {
    public static void main(String[] args) {
        test();  //运行时异常可以不处理
    }

    private static void test() {
        throw new RuntimeException("扔个异常");
    }
}

举例:throw的受查异常

public class TestString {
    public static void main(String[] args) throws Exception{
        test();  //运行时异常可以不处理
    }

    private static void test() throws Exception{
        throw new Exception("扔个异常");  //报红应处理,此处不处理扔出去
    }
}

总结:Exception和RuntimeException的区别

  1. 使用Exception是RuntimeException的父类,使用Exception定义的异常要求必须使用异常处理,而使用RuntimeException定义的异常可以由用户选择性的来进行异常处理
  2. 常见的RuntimeException:classCastException、NullPointerException等

5. 自定义异常类

  • 在Java中,针对可能出现的公共程序问题都会提供有相应的异常信息,但是这些异常信息往往不够我们使用。所以我们可以自己定义一个属于自己的异常类
  • 自定义异常类可以继承两种父类:Exception,RuntimeException
    举例:自定义异常类
public class TestString {
    public static void main(String[] args) {
        int a = 1;
        int b = 1;
        int c = a+b;
        if(c == 2){
            throw new AddEexception("此时1+1不能等于2");
        }
    }
}

class AddEexception extends RuntimeException{
    public AddEexception(String msg){
        super(msg);
    }
}

猜你喜欢

转载自blog.csdn.net/mi_zhi_lu/article/details/89787965
今日推荐