【lombok】Boolean类型属性兼容原始get/set方法

2018-07-12  本文已影响942人  7ccc099f4608

兼容性问题产生于lombok 1.16.18,没有测试过后续版本。

解决方案(问题的出现和分析看后文)

  1. 将lombok要序列化的Boolean属性,使用@JSONField注解,指定序列化后的名字为截去is后名字(首字母大小写不敏感),比如isHeheda注解为@JSONField(name = "heheda"),或者@JSONField(name = "Heheda")
  2. 手动/使用IDEA半自动显示地为Boolean属性加上gettersetter方法;
  3. 终极解决方案, 不要用is作为开头的方式来表征这是一个Boolean型属性。old school的作风有时候会害死人的。。。
package javaFirstJson;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.annotation.JSONField;
import lombok.Data;

@Data
class useLombok {
    private Long id;

    // 方法一:
    @JSONField(name = "heheda")  // 指定序列化之后的字段名,序列化时区分大小写;反序列化时不区分大小写
    private Boolean isHeheda = false;

    // 方法二:
//    public Boolean getHeheda() {
//        return isHeheda;
//    }
//
//    public void setHeheda(Boolean heheda) {
//        isHeheda = heheda;
//    }

}

class defaultGetSet {
    private Long id;
    private Boolean isHeheda = false;

    public Boolean getHeheda() {
        return isHeheda;
    }

    public void setHeheda(Boolean heheda) {
        isHeheda = heheda;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }
}

public class DiffLombokAndSet {
    public static void main(String[] args) {
        useLombok ul = new useLombok();
        ul.setIsHeheda(true);
        System.out.println("lombok 序列化:");
        System.out.println(JSON.toJSONString(ul));

        defaultGetSet df = new defaultGetSet();
        df.setHeheda(true);
        System.out.println("默认getter/setter 序列化:");
        System.out.println(JSON.toJSONString(df));


        String withIs = "{\"isHeheda\":true}";
        String withoutIs = "{\"heheda\":true}";

        System.out.println("使用lombok,反序列化");
        System.out.println(JSON.parseObject(withIs, useLombok.class));   // true
        System.out.println(JSON.parseObject(withoutIs, useLombok.class).getIsHeheda());  // false

        System.out.println("使用默认getter、setter,反序列化");
        System.out.println(JSON.parseObject(withIs, defaultGetSet.class).getHeheda());  // true
        System.out.println(JSON.parseObject(withoutIs, defaultGetSet.class).getHeheda());  // true

        /** 使用lombok, 序列化boolean, 会出现 `isSomeField`;
         *  而使用默认的getter、setter,则是someField */

        /** fastJson 1.2.41, lombok 1.16.18,
         * lombok反序列化Boolean类型时,无法自动关联 没有is的字符串 和 有is的字段 */
    }
}

输出:

lombok 序列化:
{"heheda":true}
默认getter/setter 序列化:
{"heheda":true}
使用lombok,反序列化
useLombok(id=null, isHeheda=true)
true
使用默认getter、setter,反序列化
true
true

前言

lombok 插件让生活简化了不少,一个@Data免去了一次次对每一个变量输入Alt+Enter,生成gettersetter的麻烦。然鹅,当类中有Boolean型属性,且命名为isHeheda 时,新老代码兼容问题,真的让人呵呵哒。

使用lombok让生活更美好

生成同一个类

  1. 使用lombok插件:
import lombok.Data;

@Data
class useLombok {
    private Long id;
    private Boolean isHeheda = false;
}
  1. 默认getter/setter方法
class defaultGetSet {
    private Long id;
    private Boolean isHeheda = false;

    public Boolean getHeheda() {
        return isHeheda;
    }

    public void setHeheda(Boolean heheda) {
        isHeheda = heheda;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }
}

显而易见,在实现同样功能的情况下,传统的getter/setter方法有点反人类,即使是IDEA能半自动的加上,仍然很不方便。

但是

两种方法看似相同,但是当有Boolean类型的属性时……

        useLombok ul = new useLombok();
        ul.setIsHeheda(true);
        System.out.println("lombok 序列化:");
        System.out.println(JSON.toJSONString(ul));

        defaultGetSet df = new defaultGetSet();
        df.setHeheda(true);
        System.out.println("默认getter/setter 序列化:");
        System.out.println(JSON.toJSONString(df));

输出:

lombok 序列化:
{"isHeheda":true}
默认getter/setter 序列化:
{"heheda":true}

看出差别没?

  1. lombok调用set方法时,严格按照Xxx改成setXxx;虽然传统方法大体也是如此,但是当有Boolean类型,且字段名是isXxx时,却将is自动截去,变成了setXxx
  2. 序列化后,lombok生成的是原字段,包括布尔类型的isHeheda;而传统方法,则将布尔类型的isHeheda序列化成"heheda"。

如果,序列化后的结果不影响反序列化,那么,这些差异可以直接忽略

BUT
        String withIs = "{\"isHeheda\":true}";
        String withoutIs = "{\"heheda\":true}";

        System.out.println("使用lombok,反序列化");
        System.out.println(JSON.parseObject(withIs, useLombok.class));   // true
        System.out.println(JSON.parseObject(withoutIs, useLombok.class).getIsHeheda());  // false

        System.out.println("使用默认getter、setter,反序列化");
        System.out.println(JSON.parseObject(withIs, defaultGetSet.class).getHeheda());  // true
        System.out.println(JSON.parseObject(withoutIs, defaultGetSet.class).getHeheda());  // true

输出:

使用lombok,反序列化
useLombok(id=null, isHeheda=true)
false
使用默认getter、setter,反序列化
true
true

可以看出:

  1. 传统方法的兼容性很强,无论字符串里面的是isHeheda 还是"heheda",都能反序列化成布尔类型的isHeheda
  2. lombok只能反序列化isHeheda,而由传统方法序列化成的"heheda"则不能序列化。

因此,lombok和传统方法在序列化或者反序列化的时候,似乎不好混用。但是出于代码健壮性考虑,或者为了兼容前人代码,不得不考虑解决方案。

上一篇下一篇

猜你喜欢

热点阅读