Blog 異常處理

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.nio.channels.OverlappingFileLockException;
import java.security.spec.ECField;
import java.util.logging.Logger;

public class Ans {
    public static void main(String[] args) {
        //test2();
        test4();
        test5();
        test6();
    }

    static void test0() {
        //異常分爲兩類,error和exception,error是程序嚴重錯誤,無法恢復,包括:OutOfMemoryError 內存耗盡,NoClassDefFoundError 無法加載某個Class,StackOverflowError 棧溢出。Exception是運行時錯誤,可以捕捉並恢復,分爲RuntimeException(可以不被捕捉),和非RuntimeException(必須被捕捉)
        //如果不想捕捉異常,可以在main函數中throws
    }

    static void test1() {
        //由於異常捕獲從上向下,且捕獲一個後與其並列的不會再捕獲,所以子類異常應當寫在前面
        //finally中的語句無論如何都會最後執行,且一定執行(沒有異常也執行)
    }

    static void test2() {
        class A {
            void a(String s) {
                if (s==null)
                    throw new NullPointerException();
            }

            void b() {
                try {
                    a(null);
                } catch (Exception e) {
                    throw new IllegalArgumentException();               //如果這樣做就會丟失NullPointerException的信息
                }
            }

            void b2() {
                try {
                    a(null);
                } catch (Exception e) {
                    throw new IllegalArgumentException(e);               //這樣便可以保存以前的信息
                }
            }

            void c() {
                try {
                    a(null);
                } catch (Exception e) {
                    throw new IllegalArgumentException(e);
                }
                finally {
                    throw new UnsupportedOperationException();          //這裏拋出一個異常會直接掩蓋前面的異常,因爲finally最後執行,且一段代碼只能拋出一個異常
                }                                                       //但這種情況其實很少見
            }

            void c2() throws Exception {
                Exception origin = null;
                try {
                    a(null);
                } catch (Exception e) {
                    origin = e;
                    throw new IllegalArgumentException(e);
                }
                finally {
                    Exception e = new UnsupportedOperationException();
                    if (origin!=null)
                        e.addSuppressed(origin);                        //這種方式可以解決異常掩蓋問題
                    throw e;
                }

            }
        }

        A a = new A();
        try {
            a.a(null);
        } catch (Exception ne) {
            ne.printStackTrace();                                       //這樣打印異常
        }

        try {
            a.b();
        } catch (Exception e) {
            e.printStackTrace();
        }

        try {
            a.b2();
        } catch (Exception e) {
            e.printStackTrace();
        }

        try {
            a.c();
        } catch (Exception e) {
            e.printStackTrace();
        }

        try {
            a.c2();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    static void test4() {
        //在編寫程序時我們可以使用斷言
        //這樣其實不會拋出錯誤,因爲JVM默認關閉斷言,需要在IDEA中設置,或者使用命令行
        int i = -1;
        assert i>0;                 //在這裏斷言失敗,會拋出AssertionError,由於時Error因此無法恢復,斷言常常用於開發和調試,而正式產品中應當使用異常
        System.out.println(i);

        assert i>0:"i must be larger than 0";   //斷言中可以包含信息
    }

    static void test5() {
        //在編寫程序時的一個好習慣是生成日誌,日誌的好處在於減少用於就錯的代碼,而且有詳細的信息
        //https://www.liaoxuefeng.com/wiki/1252599548343744/1264738568571776 可以查看博客信息,當然博客中講的也比較淺
        //同時這種標準庫自帶的JDK Logging不是非常好用,以後可以試試更先進的
        Logger logger = Logger.getGlobal();
        logger.info("start process");
        logger.severe("no no no");
    }

    static void test6() {
        //Commons Logging是一個第三方日誌庫,需要載入工程中,它可以掛載不同的日誌系統,默認下使用Log4j,如果沒有就是用JDK Logging
        class A {
            void a() {throw new RuntimeException(); }
        }

        Log log = LogFactory.getLog(Ans.class);
        log.info("begin");
        log.warn("end");

        try {
            A a = new A();
            a.a();
        } catch (Exception e) {
            log.error("catch it!!",e);          //這種方法可以反映捕獲異常
        }
    }

    static void test7() {
        //Log4j的功能非常強大,由於其配置不方便,開發階段如果不需要引入Log4j可以暫時使用Commons Logging,此是Commons Logging默認使用JDK Logging
        //等到需要使用Log4j時可以配置並使用,這時Commons Logging將自動切換至Log4j,不需要改動任何代碼
    }

    static void test8() {
        //相對於Log4j 與Commons Logging,還擁有另一對日誌工具SLF4J與Logback
    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章