Java变量命名前俩个字母仅含有一个大写字母的坑
背景
前几周在做项目fetch切换,即将HttpUtils调用改成使用Feign调用。大概代码如下:
// 原代码
String resultJson = HttpUtil.get(url + "/fin/test?code=" + code, null);
RespDTO<Result> respDTO = JSON.parseObject(resultJson, new TypeReference<RespDTO<Result>>() {});
// 现代码如下
RespDTO<Result> respDTO = urlClient.getTest(code);
代码上线后,出现了异常。表现为:respDTO的某个字段为null,但是第三方是有传过来这个值的。
问题复现
public static void main(String[] args) throws JsonProcessingException, IntrospectionException {
String data = "{\"aFiled\":10,\"normalFiled\":20}";
// 原方式
Domain domain = JSON.parseObject(data, Domain.class);
System.out.println("domain = " + domain.getAFiled());
// feign方式
ObjectMapper mapper = new ObjectMapper();
Domain domain1 = mapper.readValue(data, Domain.class);
System.out.println("domain1 = " + domain1.getAFiled());
}
问题分析
既然请求返回数据,但接收对象没有对应的值,那就说明字符串没有反序列化到指定的变量名上。改之前是使用FastJson反序列化数据,改之后的Feign默认是采用Jackson反序列化数据。那么为什么FastJson可以反序列化aFiled而Jackson不可以呢?
FastJson是根据变量名称来反序列化的,也就是说它接收到aFiled数据,就会到对象找aFiled变量名,然后附上值;而Jackson默认是根据JavaBean规范找到对应属性后再赋值,也就是说Jackson并没有在这个对象找到aFiled属性。
JavaBean属性名称跟变量名称是不一定相同的。JavaBean是通过对象的get、set方法来确定对象属性,其属性名称是由其对象变量来决定的,通常的逻辑是:将属性首字母转成大写。但也有例外就是,前俩个字母都是大写的情况:
8.8 Capitalization of inferred names.
When we use design patterns to infer a property or event name, we need to decide what rulesto follow for capitalizing the inferred name. If we extract the name from the middle of a normalmixedCase style Java name then the name will, by default, begin with a capital letter.
Java programmers are accustomed to having normal identifiers start with lower case letters.Vigorous reviewer input has convinced us that we should follow this same conventional rulefor property and event names.
Thus when we extract a property or event name from the middle of an existing Java name, wenormally convert the first character to lower case. However to support the occasional use of allupper-case names, we check if the first two characters of the name are both upper case and ifso leave it alone. So for example,
“FooBah” becomes “fooBah”
“Z” becomes “z”
“URL” becomes “URL”
We provide a method Introspector.decapitalize which implements this conversion rule.
而Jackson根据get、set方法来确定属性的名称。而变量前俩个字母含有一个大写字母对应的属性名称会很怪。如下:

我们项目上使用的是lombok,其生成的get、set方法是不遵循JavaBean规范的,只是将变量名的首字母大写而已,所以它生成aFiled的方法是getAFiled。
所以,Jackson在接收到aFiled属性值,它会到对象找setaFiled方法,自然这个对象是没有这个方法的,所以就没映射到aFiled字段上。
解决办法
jackson可以使用@JsonProperty注解来指定属性名称。
总结
出现这个就是因为JavaBean规范对前俩个字母含有大写字母的变量名做了特殊处理。 Jackson遵循JavaBean规范来反序列化,而项目使用的Lombok插件是不遵循JavaBean规范。

扩展
JavaBean规范对前俩个字母含有大写字母的处理不全
针对变量名前俩个字母做个穷举,就是如下对象:
public class Domain {
private Integer aFiled;
private Integer afiled;
private Integer AFiled;
private Integer Afiled;
public Integer getaFiled() {
return aFiled;
}
public void setaFiled(Integer aFiled) {
this.aFiled = aFiled;
}
public Integer getAfiled() {
return afiled;
}
public void setAfiled(Integer afiled) {
this.afiled = afiled;
}
public Integer getAFiled() {
return AFiled;
}
public void setAFiled(Integer AFiled) {
this.AFiled = AFiled;
}
}
你会发现afiled和Afiled生成的属性是一致的!不过好在项目中没有人只将首字母大写这种命名风格。
谨慎用Lombok替换旧项目的get、set方法
旧项目一般都是用Idea来生成get、set方法,而Idea是遵循JavaBean规范来生成属性的。所以,旧项目如果含有前俩个仅含有一个大写字母时,尽量不用药lombok去替换。
参考链接
Java变量命名前俩个字母仅含有一个大写字母的坑的更多相关文章
- input输入框输入小写字母自动转换成大写字母
input输入框输入小写字母自动转换成大写字母有两种方法 1.用js onkeyup事件,即时把字母转换为大写字母: html里input加上 <input type="text&qu ...
- sap保存时小写字母自己主动转大写字母的解决方法
在实际应用中.ABAP保存数据到后台数据库表中时.会自己主动把前台输入的小写字母自己主动转换为大写字母来保存.有时候客户可能不须要转换,就须要用到以下的方法: 1.找到相应字段的Data ...
- python实现输入任意一个大写字母生成金字塔的示例
输入任意一个大写字母,生成金字塔图形 def GoldTa(input): L = [chr(i) for i in range(65, 91)] # 大写字母A--Z idA = 65 # 从A开始 ...
- 菜鸟笔记:java变量命名及峰驼式命名法
如同酒店会给每个房间起个性化的名字一样,程序中的变量也需要用合理的名字进行管理---变量名! 需要注意,给酒店房间起名字时可以是数字,如"802",也可以是有趣的名字,如" ...
- java基础之Java变量命名规范
本文介绍的是java中的变量的命名规则,对于初学者来说,还是很重要的.希望对你有帮助,一起来看. Java是一种区分字母的大小写(case-sensitive)的语言,下面谈谈Java语言中包.类.变 ...
- 转型、java基础之Java变量命名规范 (转载)
向上转型:基类引用指向导出类(派生类)的对象(实例)向下转型:导出类的引用指向基类的对象(实例) 重点:向下转型只有将该引用的导出类的向上转型后向下转型,运行时才不会报错 Java是一种区分字母的大 ...
- Java变量命名规范
java命名规范 所有方法.变量.类名:见名知意 类成员变量:首字母小写.驼峰原则: 例如:lastName 第一个单词首字母小写,其余首字母大写 局部变量:首字母小写.驼峰原则 类名: 首字母小写. ...
- java变量命名规则
1. 变量必须以字母,下划线”_”或”$”符号开 2. 变量可以包括数字,但不能以数字开 3. 除了下划线”_”和”$”符号以外,变量名不能包含任何特殊字符 4. ...
- 《Java程序员面试笔试宝典》之Java变量命名有哪些规则
在Java语言中,变量名.函数名.数组名统称为标识符,Java语言规定标识符只能由字母(a~z,A~Z).数字(0~9).下划线(_)和$组成,并且标识符的第一个字符必须是字母.下划线或$.此外,标识 ...
随机推荐
- 【原】“Error getting 'android:label' attribute”
项目上线过程中遇到“Error getting 'android:label' attribute: attribute is not a string value”这个错误. 备忘下:是因为有act ...
- VS提交码云权限问题
提交代码时出现Git failed with a fatal error. Authentication failed的问题. 如果没有像当前代码库提交过代码(所有项目),那么提交时会提示输入账号密码 ...
- 面经手册 · 第10篇《扫盲java.util.Collections工具包,学习排序、二分、洗牌、旋转算法》
作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 算法是数据结构的灵魂! 好的算法搭配上合适的数据结构,可以让代码功能大大的提升效率. ...
- ThinkPHP6.0 判断是否有文件上传
有必要考虑不是post请求或没有指定enctype="multipart/form-data"的情况.如果是post请求还是设置了正确的编码,没有文件上传时 request()-& ...
- centos7新增用户并授权root权限、非root用户启动tomcat程序
一.centos7新增用户并授权root权限 cat /etc/redhat-release查看centos版本号 1.禁用root账户登录 vim /etc/ssh/sshd_config 找到这一 ...
- python3中抛异常except后面参数
try: xxx except exception as e: print("给exception取了个别名叫做e") else: ccc
- pytest文档1-pytest+Allure+jenkins+邮箱发送
前言: 1.pytest+allure是目前很多公司使用较多的一种报告样式,因为它更详细,各种指标更直观(简单的说就是看着更高大上,更能装X). 环境准备: 1.Windows10 2.Allure ...
- 算法数据结构 | 三个步骤完成强连通分量分解的Kosaraju算法
强连通分量分解的Kosaraju算法 今天是算法数据结构专题的第35篇文章,我们来聊聊图论当中的强连通分量分解的Tarjan算法. Kosaraju算法一看这个名字很奇怪就可以猜到它也是一个根据人名起 ...
- openstack核心组件——keystone身份认证服务(5)
云计算openstack核心组件——keystone身份认证服务(5) 部署公共环境 ntp openstack mariadb-server rabbitmq-server memcache 1.w ...
- 分布式系统监视zabbix-安装
zabbix概述 Zabbix是什么 Zabbix 是由Alexei Vladishev创建,目前由Zabbix SIA在持续开发和支持. Zabbix 是一个企业级的分布式开源监控方案. Zabbi ...