js获取网站广告点击量怎么做,营销推广活动策划方案,wordpress中文主题框架,建设工程施工合同示范文本2021一、前言
在阿里编码规约中#xff0c;有一个约定如下 【强制】POJO 类中的任何布尔类型的变量#xff0c;都不要加 is 前缀#xff0c;否则部分框架解析会引起序列 化错误。 但为什么类中的field不能用is开头呢#xff1f;本文将从问题演示、框架源码#xff08;本文使用…一、前言
在阿里编码规约中有一个约定如下 【强制】POJO 类中的任何布尔类型的变量都不要加 is 前缀否则部分框架解析会引起序列 化错误。 但为什么类中的field不能用is开头呢本文将从问题演示、框架源码本文使用的Jackson两个方面来进行阐述。
二、问题演示
本文使用的Jackson需要引入相关依赖maven依赖如下gradle配置请自行寻找。
dependencygroupIdcom.fasterxml.jackson.core/groupIdartifactIdjackson-databind/artifactIdversion2.11.0/version
/dependency首先写一个简单的POJO在这个POJO中有三个属性分别是isSuccess/code/msg并自动生成了对应的get方法这里要注意isSuccess属性对应的get方法名也是isSuccess()。代码如下
public class Pojo {private boolean isSuccess;private int code;private String msg;private Pojo(boolean success, int code, String msg) {this.isSuccess success;this.code code;this.msg msg;}public static Pojo buildSuccess() {return new Pojo(true, 2000, success);}public boolean isSuccess() {return isSuccess;}public int getCode() {return code;}public String getMsg() {return msg;}Overridepublic String toString() {return Pojo{ isSuccess isSuccess , code code , msg msg \ };}
}然后再写一个类在这个类中测试对POJO的序列化。在主函数中会先创建一个POJO然后将其打印接着会使用Jackson中的ObjectMapper将对象序列化成Json字符串并打印。
public class Main {public static void main(String[] args) {ObjectMapper mapper new ObjectMapper();Pojo pojo Pojo.buildSuccess();System.out.println(raw pojo1: pojo.toString());try {System.out.println(serialize pojo1: mapper.writeValueAsString(pojo));} catch (IOException e) {System.out.println(e);}}
}执行main()方法后得到运行结果如下图 可以发现使用ObjectMapper对象将POJO序列化成String后输出的变量名是success而原有POJO中的变量isSuccess丢失。将该Json串反序列化成对象会出现问题。
三、源码解析
// TODO 待源码大致读懂后再补充
源码看不太懂只讲解一下核心的流程。由于Jackson扩展性很好对各种复杂情况都进行了处理这里只讲解最普通的分支流程。
主要方法是POJOPropertiesCollector#collectAll() protected void collectAll(){LinkedHashMapString, POJOPropertyBuilder props new LinkedHashMapString, POJOPropertyBuilder();// First: gather basic data_addFields(props); // note: populates _fieldRenameMappings_addMethods(props);// 25-Jan-2016, tatu: Avoid introspecting (constructor-)creators for non-static// inner classes, see [databind#1502]if (!_classDef.isNonStaticInnerClass()) {_addCreators(props);}// Remove ignored properties, first; this MUST precede annotation merging// since logic relies on knowing exactly which accessor has which annotation_removeUnwantedProperties(props);// and then remove unneeded accessors (wrt read-only, read-write)_removeUnwantedAccessor(props);// Rename remaining properties_renameProperties(props);// and now add injectables, but taking care to avoid overlapping ones// via creator and regular properties_addInjectables(props);// then merge annotations, to simplify further processing// 26-Sep-2017, tatu: Before 2.9.2 was done earlier but that prevented some of// annotations from getting properly mergedfor (POJOPropertyBuilder property : props.values()) {property.mergeAnnotations(_forSerialization);}// And use custom naming strategy, if applicable...PropertyNamingStrategy naming _findNamingStrategy();if (naming ! null) {_renameUsing(props, naming);}// Sort by visibility (explicit over implicit); drop all but first of member// type (getter, setter etc) if there is visibility differencefor (POJOPropertyBuilder property : props.values()) {property.trimByVisibility();}// and, if required, apply wrapper name: note, MUST be done after// annotations are merged.if (_config.isEnabled(MapperFeature.USE_WRAPPER_NAME_AS_PROPERTY_NAME)) {_renameWithWrappers(props);}// well, almost last: theres still ordering..._sortProperties(props);_properties props;_collected true;}四、结论
通过上述论证我们不难发现类中的属性用is开头会导致对象序列化后产生意想不到的结果。所以在平时编码的过程中我们不能在类变量中用is开头如: “isSuccess”这样容易造成程序错误。
如果情况特殊也不必墨守成规只是需要预先判断可能产生的影响、影响范围、能否监控等问题。更特殊的情况你可以将变量名定义为isIsSuccess或者将isSuccess定义为public。