is开头boolean属性序列化问题

JavaBean类的属性的类型是boolean类型,那么该属性的读方法的格式可以是isXxx()或者getXxx(),例如,名为state的boolean类型的属性,它的读方法可以是isState()或者是getState()。

【强制】POJO 类中的任何布尔类型的变量,都不要加 is 前缀,否则部分框架解析会引起序列
化错误。
反例:定义为基本数据类型 Boolean isDeleted 的属性,它的方法也是 isDeleted(),框架在反向解析的时候,“误以为”对应的属性名称是 deleted,导致属性获取不到,进而抛出异常。

一、布尔类型IDE自动生成的Get方法

  1. is开头boolean
public class testBoolean {
	private boolean isTestBoolean;
	
	public boolean isTestBoolean() {
		return isTestBoolean;
	}
}
  1. 非is开头boolean
public class testBoolean {
	private boolean testBoolean;
	
	public boolean isTestBoolean() {
		return testBoolean;
	}
}

基础数据类型boolean属性不管属性名是否是is开头IDE自动生成的getter方式都是isXxx()。

二、Gson、Jackson和FastJson序列化的区别

测试类

static class TestJsonBoolean {

        private boolean isBooTest;

        // IDE自动生成的getter方法
        public boolean isBooTest() {
            return isBooTest;
        }

        public void setBooTest(boolean booTest) {
            isBooTest = booTest;
        }

        // 类中不存在的属性
        public String getTestAtt() {
            return "testatt";
        }
    }

分别使用Gson、Jackson和FastJson对类进行初始化。

public static void main(String[] args) throws JsonProcessingException {
        TestJsonBoolean test = new TestJsonBoolean();
        test.setBooTest(true);

        String gJson = new Gson().toJson(test);// Gson序列化
        String jJson = new ObjectMapper().writeValueAsString(test); // Jackson序列化
        String fJson = JSON.toJSONString(test);// FastJson序列化

        System.out.println("GsonToJson:" + gJson);
        System.out.println("JacksonToJson:" + jJson);
        System.out.println("FastJsonToJson:" + fJson);
    }

输出结果

GsonToJson:{"isBooTest":true}
JacksonToJson:{"booTest":true,"testAtt":"testatt"}
FastJsonToJson:{"booTest":true,"testAtt":"testatt"}

可见这三种序列化工具的序列化方式还是有所差异,Gson是根据类中属性进行序列化,所以结果没什么问题。而Jackson和FastJson的序列化方式是先找到getter方法,再根据JavaBean规范生成对应的属性名,所以不仅isBooTest属性被序列化成booTesttestAtt这个类中根本不存在的属性也在序列化的结果中。

三、产生的问题

测试类

static class TestJsonBoolean {

        private boolean isBooTest;

        // IDE自动生成的getter方法
        public boolean isBooTest() {
            return isBooTest;
        }

        public void setBooTest(boolean booTest) {
            isBooTest = booTest;
        }

        @Override
        public String toString() {
            return "TestJsonBoolean{" +
                    "isBooTest=" + isBooTest +
                    '}';
        }
    }

使用Gson反序列化Jackson或FastJson序列化结果

public static void main(String[] args) throws JsonProcessingException {
        TestJsonBoolean test = new TestJsonBoolean();
        test.setBooTest(true);

        // 使用Jackson序列化
        String jJson = new ObjectMapper().writeValueAsString(test);
        System.out.println("JacksonToJson:" + jJson);
        // 使用Gson反序列化Jackson序列化结果
        System.out.println("JsonToObj:" + new Gson().fromJson(jJson, TestJsonBoolean.class));

    }

输出结果

JacksonToJson:{"booTest":true}
JsonToObj:TestJsonBoolean{isBooTest=false}

在使用Gson对Jackson或FastJson的序列化结果进行反序列化时,由于序列化结果中将isBooTest属性序列化为booTest,Gson对其反序列化时没有找到该属性且基础数据类型给了默认值false,出现了序列化前后结果不一致。

四、总结

不要在类中为boolean类型属性命名以is开头,这点在阿里的开发手册也有明确说明。

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值