【Java】斷言 assert

6.Java中的異常、斷言、日誌【草稿中】
如何開啓Java的斷言?

簡單說斷言就等於 對一個布爾表達式進行判別,如果爲真,那麼相安無事,如果爲假,那麼拋出異常

首先是第一個博客裏的第一段代碼

//代碼段A
public class AssertionDriver {
    public static void main(String args[]){
        Employee employee = new Employee();
        employee.setName("Lang Yu");
        employee.setEmail("[email protected]");
        businessProcess(employee);
    }
    
    public static void businessProcess(Employee employee){
        try{
            assert employee.getName() != null && 
                employee.getEmail() != null && 
                employee.getPassword() != null:
                    employee;
        }catch(AssertionError error){
            System.out.println(error);
        }
    }
}

class Employee{
    private String name;
    private String email;
    private String password;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getEmail() {
        return email;
    }
    public void setEmail(String email) {
        this.email = email;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
    @Override
    public String toString(){
        return "/nName:" + name + "/n" + "Email:" + email + "/n" + "Password:" + password;
    }
}
/*下面是代碼出處
————————————————
版權聲明:本文爲CSDN博主「戒子豬」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/silentbalanceyh/article/details/4564884
*/

爲什麼呢第一段代碼不好使呢?
首先我們需要知道的是java裏默認是關閉了斷言的功能的,如果我們想用斷言,就得手動開啓,那麼如何開啓呢?

package others;

class Loaded
{
    public void go()
    {
        try
        {
            assert false:"Loaded.go()";
        }
        catch(AssertionError error){
            System.out.println(error);
        }
    }
}

public class LoaderAssertions
{
    public static void main(String[] args)
    {
        ClassLoader.getSystemClassLoader().setDefaultAssertionStatus(true);
        new Loaded().go();
    }
}

上面的代碼是可以拋出斷言異常的,但當我們把ClassLoader.getSystemClassLoader().setDefaultAssertionStatus(true);註釋掉,這個代碼就不會拋出斷言異常。另一種方式是,我們可以把上面那段代碼註釋掉,但需要配置運行參數,如下所示

Run —> Run Configurations —> 選擇 Arguments 選項卡
在 VM arguments 文本框中輸入“-ea” 如果輸入 -da 表示禁止斷言

如果我們對運行參數進行了配置,第一段代碼是能夠拋出異常的。
那如果我不想配置運行參數,我希望在代碼裏手動開啓呢?理所應當地在代碼裏添加了ClassLoader.getSystemClassLoader().setDefaultAssertionStatus(true);,如下面代碼所示

//代碼段B
public class AssertionDriver {
    public static void main(String args[]){
    	ClassLoader.getSystemClassLoader().setDefaultAssertionStatus(true);
        Employee employee = new Employee();
        employee.setName("Lang Yu");
        employee.setEmail("[email protected]");
        businessProcess(employee);
    }
    
    public static void businessProcess(Employee employee){
        try{
            assert employee.getName() != null && 
                employee.getEmail() != null && 
                employee.getPassword() != null:
                    employee;
        }catch(AssertionError error){
            System.out.println(error);
        }
    }
}

class Employee{
    private String name;
    private String email;
    private String password;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getEmail() {
        return email;
    }
    public void setEmail(String email) {
        this.email = email;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
    @Override
    public String toString(){
        return "/nName:" + name + "/n" + "Email:" + email + "/n" + "Password:" + password;
    }
}

我發現上述代碼並不能按我們所想拋出斷言異常,於是我進行了各種嘗試修改,改成下面那樣就可以了

//代碼段C
package others;

public class AssertionDriver {
    public static void main(String[] args) {
//        ClassLoader.getSystemClassLoader().setDefaultAssertionStatus(true);
        ClassLoader.getSystemClassLoader().setClassAssertionStatus("others.Employee",true);
//        AssertionDriver.class.getClassLoader().setDefaultAssertionStatus(true);
//        上面是設置斷言開啓的三種方式
        System.out.println(AssertionDriver.class.getClassLoader());
        System.out.println(Employee.class.getClassLoader());
        System.out.println(ClassLoader.getSystemClassLoader());
//        上述三個類加載器相同
        Employee employee = new Employee();
        employee.setName("Lang Yu");
        employee.setEmail("[email protected]");
        employee.businessProcess();
    }
}


class Employee {
    public void businessProcess() {
        try {
            boolean check = this.getName() != null &&
                    this.getEmail() != null &&
                    this.getPassword() != null;
            assert check : this.toString();
        } catch (AssertionError error) {
            System.out.println(error);
        }
    }

    private String name;
    private String email;
    private String password;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    @Override
    public String toString() {
        return "\nName:" + name + "\n" + "Email:" + email + "\n" + "Password:" + password;
    }
}

爲什麼呢?
第一篇博客裏也說到了,我們可以允許某一部分的類和包開啓斷言功能,其他的類不允許(即使在這些不允許的類裏使用了Assert,這些語句會被跳過),但前提是,得在這個類被加載之前進行設置,因爲如果類都加載完成了,那再設置就不管用了啊。同時我們要知道,類加載的時機是第一次遇到這類的時候(包括第一次調用靜態方法、第一次調用構建方法等)
代碼段B中,Assert語句被用於AssertionDriver類中,而這個類是程序的入口類,即運行主程序之前,這個類就已經被加載完畢了,我們再去打開斷言開關,已經影響不了AssertionDriver類了,而又是因爲默認是關閉的,所以用不了了。
而代碼段C中,Assert語句被用於Employee類,當執行到打開斷言語句的時候,這個類還沒有被加載進來,所以可以成功爲Employee類打開斷言。代碼段C裏有着三種開啓的方式。

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