带你从头到尾解释为什么阿里巴巴规范中强制布尔类型不要加is?三种java的json解析框架jackson、gson、fasterjson的用法和解析

查看阿里巴巴规范,可以看到有一条强制性的要求。
POJO类中布尔类型的变量不要加is,第一次看到这个的时候有点懵。基本数据类型Boolean?Boolean不是boolean的包装类型吗,后发现这里应该是笔误了,应该是基本数据类型boolean。但是后面又是什么意思呢?我们做个实验来看一下
在这里插入图片描述

第一步:在pom.xml中分别引入在java中常用的json解析框架。

<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.13.1</version>
</dependency>

<!-- https://mvnrepository.com/artifact/com.google.code.gson/gson -->
<dependency>
    <groupId>com.google.code.gson</groupId>
    <artifactId>gson</artifactId>
    <version>2.8.9</version>
</dependency>

<!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.79</version>
</dependency>

第二步:添加一个用于测试的pojo类

class Course {
    private boolean isExpire;

    public boolean isExpire() {
        return isExpire;
    }

    public void setExpire(boolean expire) {
        isExpire = expire;
    }
}

可以看到,对于基本类型的boolean值,如果字段名中包含is,则自动生成出来的getter、setter中,getter方法的名字和字段名是一样的,而setter方法的is则被自动去掉了。那么,不同的框架对于这种情况会怎么处理呢,接下来编写测试类进行测试。

第三步:编写测试类,分别使用不同的框架进行测试

    @Test
    public void testJson() throws JsonProcessingException {
        System.out.println("jackson");
        System.out.println(new ObjectMapper().writeValueAsString(new Course()));
        System.out.println("==========================");
        System.out.println("gson");
        System.out.println(new Gson().toJson(new Course()));
        System.out.println("==========================");
        System.out.println("fastjson");
        System.out.println(JSON.toJSONString(new Course()));
    }

查看控制台输出

jackson
{"expire":false}
==========================
gson
{"isExpire":false}
==========================
fastjson
{"expire":false}

根据控制台输出,可以看到:jackson和fastjson解析出来的json字段都叫expire,而gson解析出来的字段叫isExpire,所以我们可以推断出来jackson和fastjson都是利用其中的get方法进行解析的,而gson则是使用的字段名进行解析。

注意,把对象解析成json字符串是不需要用到set方法的。可以把set方法去掉进行测试,发现是不会报错的,也能正常输出结果。

class Course {
   private boolean isExpire;

   public boolean isExpire() {
       return isExpire;
   }
}

但是,如果把get方法也去掉,就会出问题了。
可以自己进行试验,结论就是:
对于jackson框架,如果没有get方法会抛出JsonProcessingException
对于gson框架,如果没有get方法也是能正常解析的,因为他是基于字段解析的。
对于fsonjson框架,如果没有get方法返回{}

实验一:修改pojo的类型为Boolean

既然基本类型boolean,难道其包装类型Boolean就没问题了吗?
把基本类型boolean,改成Boolean,重写生成getter、setter方法进行测试

class Course {
    private Boolean isExpire;

    public Boolean getExpire() {
        return isExpire;
    }

    public void setExpire(Boolean expire) {
        isExpire = expire;
    }
}

再次运行测试类,查看控制台输出

jackson
{"expire":null}
==========================
gson
{}
==========================
fastjson
{}

可以看到jackson解析出来了字段名为expire,并且值为null,这是因为jackson是使用get方法来解析的,而get方法叫做getExpire,所i有解析出来的字段名叫做expire,至于为什么是null是因为所有引用类型的默认值都是null
而gson和fastjson对于null值的属性则不进行解析了。

实验二:修改pojo的字段为expire,类型为boolean

既然名字中有is就会出问题,那我把is去掉行了吧?

class Course {
    private boolean expire;

    public boolean isExpire() {
        return expire;
    }

    public void setExpire(boolean expire) {
        this.expire = expire;
    }
}

运行测试类,查看测试结果。

jackson
{"expire":false}
==========================
gson
{"expire":false}
==========================
fastjson
{"expire":false}

可以看到,三种框架解析出来的结果都是一样的。那如果是引用类型的Boolean呢?

实验三:修改pojo的字段为expire,类型为Boolean

class Course {
    private Boolean expire;

    public Boolean getExpire() {
        return expire;
    }

    public void setExpire(Boolean expire) {
        this.expire = expire;
    }
}
jackson
{"expire":null}
==========================
gson
{}
==========================
fastjson
{}

可以看到,和实验一的结果是一样的。

总结:

  1. 如果我们的字段名中包含isXxx,那么如果是用的基本类型boolean,则自动生成出来的getter方法叫做,isXxx,和我们的字段名会一样;如果用的引用类型boolean,则自动生成出来的getter方法叫走getXxx,原字段名中的is就没有了!无论是基本类型还是引用类型,生成出来的名字都不是我们想要的,当然我们可以自行修改生成出来的名字,但是会增大工作量,而且一个开发团队,在多人协作的情况下,有时无疑会增大我们的debug时间和沟通时间,产生意想不到的结果。
  2. jackson和fasterjson都是用对象的get方法进行解析成json字符串的,如果没有get方法会出问题。而gson框架则是对字段进行解析,即使没有get方法也不会报错。但是,我们一般都会会生成get、set方法的。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值