zoukankan      html  css  js  c++  java
  • 廖雪峰Java3异常处理-1错误处理-3抛出异常

    1.异常的传播

    当某个方法抛出异常时:

    • 如果当前方法没有捕获,异常就被抛到上层调用方法
    • 直到遇到某个try...catch被捕获
    • 使用printStackTrace()打印处方法的调用栈
    import java.lang.String;
    
    public class Main {
        public static void main(String[] args) {
            try{
                process1();
            }catch (Exception e){
                e.printStackTrace();//对于调试错误非常有用
            }
        }
        static void process1(){
            process2();
        }
        static void process2() {
            Integer.parseInt(null);
        }
    }
    

    2.抛出异常

    • 创建某个Exception的实例
    • 用throw语句抛出
    import java.lang.String;
    
    public class Main {
        public static void main(String[] args) {
            try{
                process1("");
            }catch (Exception e){
                e.printStackTrace();
            }
        }
        static void process1(String s){
            throw new IllegalArgumentException();
        }
    }
    

    3.转换异常与持有原有异常

    3.1转换异常

    如果一个方法捕获了某个异常后,又在catch子句中抛出新的异常,就相当与把抛出的异常类型“转换”了。

    import java.lang.String;
    
    public class Main {
        public static void main(String[] args) {
            process1("");
        }
        static void process1(String s){
            try{
                process2(s);
            }catch (NullPointerException e){
                throw new IllegalArgumentException();//捕获NullPointerException,抛出IllegalArgumentException
            }
        }
        static void process2(String s){
            throw new NullPointerException();
        }
    }
    
    ## 3.2转换的异常持有原有异常 上例中存在的问题:新的异常丢失了原始异常信息,只追踪到process1。如何让新的Exception可以持有原始异常信息? 解决方法:将异常传入即可。 throw new IllegalArgumentException(e); ```#java import java.lang.String;

    public class Main {
    public static void main(String[] args) {
    process1("");
    }
    static void process1(String s){
    try{
    process2(s);
    }catch (NullPointerException e){
    throw new IllegalArgumentException(e);
    }
    }
    static void process2(String s){
    throw new NullPointerException();
    }
    }

    <img src="https://img2018.cnblogs.com/blog/1418970/201901/1418970-20190129145215827-451969646.png" width="700" />
    
    #    4.被屏蔽的异常suppressed exception
    在抛出异常前,finally语句会保证执行。
    <font color=#9400D3>如果finally语句抛出异常,则catch语句不再抛出,没有被抛出的异常被称为“被屏蔽”的异常(suppressed exception)</font>
    ```#java
    import java.lang.String;
    
    public class Main {
        public static void main(String[] args) {
            try{
                process1("");
            }catch (Exception e){
                System.out.println("catched");
                throw new RuntimeException(e);//“被屏蔽”的异常(suppressed exception)
            }finally {
                System.out.println("finally");
                //throw new NullPointerException();
            }
        }
        static void process1(String s){
            throw new IllegalArgumentException();
        }
    }
    

    finally中不抛出异常

    finally中抛出异常
    throw new NullPointerException();去掉注释

    因此尽量避免在finally中抛出异常

    5.如何保存所有的异常信息

    • 使用origin变量保存原始异常
    • 如果存在原始异常,用addSuppressed()添加新异常
    • 如果存在原始异常,或者新异常,最后在finally抛出
    import java.lang.String;
    
    public class Main {
        public static void main(String[] args) throws Exception {
            Exception origin = null;
            try{
                process1("");
            }catch (Exception e){
                origin = e;
                System.out.println("catch捕捉到了");
                throw new RuntimeException("可能屏蔽的异常"+e);
            }finally {
                System.out.println("finally");
                try{
                    throw new NullPointerException("finally 抛出的异常");
                }catch (Exception e){
                    if (origin != null ){
                        origin.addSuppressed(e);
                    }else{
                        origin = e;
                    }
                }
                if (origin != null){
                    throw origin;
                }
            }
        }
        static void process1(String s){
            throw new IllegalArgumentException("process1方法异常了,32");
        }
    }
    
    ## 5.2获取所有的异常信息 因为一般不在finally中捕获异常,所以可以直接使用for循环将异常信息打印出来。 ```#java import java.lang.String;

    public class Main {
    public static void main(String[] args) throws Exception {
    Exception origin = null;
    try{
    process1("");
    }catch (Exception e){
    e.printStackTrace();
    for(Throwable t:e.getSuppressed()){
    t.printStackTrace();
    }
    }finally {
    System.out.println("finally");
    }
    }
    static void process1(String s){
    throw new IllegalArgumentException("process1方法异常了,32");
    }
    }

    <img src="https://img2018.cnblogs.com/blog/1418970/201901/1418970-20190129173524625-1932720916.png" width="700" />
    
    
    #    6.总结:
    *    printStackTrace()可以打印异常的传播栈,对于调试非常有用
    *    捕获异常并再次抛出新的异常时,应该持有原有异常信息。即新抛出的异常应该包含原始异常。
    *    如果在finally中抛出异常,应该把新抛出的异常添加到原有异常中
    *    用getSuppressed()可以获取所有添加的Suppressed Exception
    *    处理Suppressed Exception要求JDK>= 1.7
  • 相关阅读:
    Django 报错RuntimeError: Model class apps.alarms.models.SendAlarmRecord doesn't declare an explicit app_label and isn't in an application in INSTALLED_APPS.
    Go获取Windows下的窗口
    linux中得到当前目录指定文件或者目录的绝对路径
    关于在IDEA中使用maven的运行test目录下的main方法无法找到类的?
    数值变量互换的三种方式
    对于List和普通数组元素怎么去重的方法
    UE编辑器UltraEdit格式化XML数据
    java操作JSON字符串转换成对象的时候如何可以不建立实体类也能获取数据
    java设置RabbitMQ的消费处理出现:ConditionalRejectingErrorHandler : Execution of Rabbit message listener failed.
    org.springframework.http.converter.HttpMessageNotReadableException
  • 原文地址:https://www.cnblogs.com/csj2018/p/10306060.html
Copyright © 2011-2022 走看看