【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("silentbalanceyh@126.com");
        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("silentbalanceyh@126.com");
        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("silentbalanceyh@126.com");
        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里有着三种开启的方式。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值