事情的起因是我再自测我自己的需求,开始写单元测试,测试自己的业务代码,其中有个场景我用到了 json,toString()像将实体对象转为 JSON 字符串,但是遇到了问题
我准备了一个 person 实体类,该类有两个字段 id,name
private String name;
private Integer id;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Integer getTest() {
System.out.println("我执行这个方法了.....");
return id + 100;
}
public void SetTest(Integer id) {
System.out.println("id = " + id);
}
然后我再单元测试中增加了这么一段方法
Person person = new Person("xiaoming",1);
String json = JsonUtils.toJson(person);
按我原本设想应该是返回这样子的字符串
{"name":"xiaoming","id":1}
但是当我运行的时候,我发现他返回的结果是不一样的,竟然夹杂了其他的字段
{"name":"xiaoming","id":1,"test":101}
看到这个结果,我惊奇了,我在想哪来的 test 字段,难道是父类的,但是我也没有继承父类,经过 debug 调试,我发现他最终会走在这个方法
public Integer getTest() {
System.out.println("我执行这个方法了.....");
return id + 100;
}
然后我意识到,json 反序列为对象,可能是根据方法命名的问题,通过 get,set 前缀命名,这情况可能是 JSON 把他当作了需要反射填充的属性字段了,然后我将方法名给改了,才最终返回我想要的结果
回到我实际业务中,我这边有很多数据源类型,比如,HIVE,PGSQL,MYSQL,SPARK_SQL 等等,需要验证连接和获取连接,我用了抽象工厂模式,实现了一个顶层父类,涉及到的一些公共参数,也将其抽离成父类,然后因为项目用到了领域驱动模式,有些实体行为应该放到自己的聚合领域,比如这些 JDBC 连接的数据源,都需要获取 jdbcUrl,而这个 jdbcUrl 是根据前端传递的参数,动态生成的,所以我就各自实体都实现了这个接口的 getJdbcUrl,这个方法,问题就来了,JSON 反序列这些对象的时候,都不自觉的走到这个 getJdbcUrl 方法里面去了,所以导致了一些意想不到的结果
所以最好是规范命名,尽可能避免在可能会反序列化对象里面方法用 get set ,is 这种有二义性的前缀命名