JavaBeans 规范
JavaBeans Specification
8 Introspection
8.8 Capitalization of inferred names.
When we use design patterns to infer a property or event name, we need to decide what rules to follow for capitalizing the inferred name. If we extract the name from the middle of a normal mixedCase 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 rule for property and event names.Thus when we extract a property or event name from the middle of an existing Java name, we normally convert the first character to lower case. However to support the occasional use of all upper-case names, we check if the first two characters of the name are both upper case and if so 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 rul
当我们使用设计的模式推断属性或者时间的名称时,我们需要判断遵循何种方式将推断名称首字母大写。如果我们从普通的混合大小写样式的 java 名称中提取对应的名称,默认情况下,名称将以大写字母开头。
java 程序员习惯于使用将普通标识以小写字母开头。那些积极的审稿人提出的意见使我们相信应用以相同的惯例规则来处理属性和事件名称。
于是当我们从已有的 java 名称中提取属性和事件名称时,我们通常将第一个字母小写。然而为了支持偶尔使用的全大写名称,我们检查名称的前两个字母是否都是大写,如果是则不做处理。例如
“FooBah” ->“fooBah”
“Z” ->“z”
“URL” ->“URL”
我们提供了方法 Introspector.decapitalize 来实现转换规则。
问题是如何产生的
图 1
图 1 中列举了前两个字母分别大小写组合出的四种情况,根据 java 自省( Introspection
)原则推断的变量名,第一行第三列展示了对这些推断出的变量名生成 getter
方法后的结果
举例
可以看到当变量名中第一个字母为小写,第二个字母为大写时,那些遵循“首字母大写习惯”的框架、程序在和别的框架、程序一起工作时产生意料之外的结果。这些情况在使用外部序列化框架、类似 BeanUtils 复制字段值到新对象等场景下将可能意外出现,即使同一框架,也可能在后续升级中改变策略导致问题。
- fastjson 在版本升级过程中,字段和
getter
setter
的对应关系由首字母大写习惯变更为 Java 的自省规则导致序列化反序列化结果不一直。
- lombok 生成的
getter
setter
方法符合首字母大写习惯,不符合 Java 的自省规则,使用 lombok 后序列化反序列化,或者使用 BeanUtils 复制属性将出现问题。
结论
所以,应避免形如首字母小写,第二个字母大写的命名方式,如:aBxxx
。
包括 Java 程序中的类字段、数据库中列名等场景要做相关考虑,避免类字段 aBxxx
,数据库列名 a_bxxx
等命名方式。