前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >警惕不规范的变量命名

警惕不规范的变量命名

作者头像
kirito-moe
发布2018-04-27 11:42:56
1.9K0
发布2018-04-27 11:42:56
举报

就在最近,项目组开始强调开发规范了,今天分享一个变量名命名不规范的小案例,强调一下规范的重要性。

Boolean变量名命名规范

16年底,阿里公开了《Java开发规范手册》,其中有一条便是“布尔类型不能以is为前缀”。规范中没有举出例子,但是给出了原因:会导致部分序列化框架的无法解析。

看看错误的示范,会导致什么问题,以Spring中的jdbcTemplate来进行实验。

定义实体类

代码语言:javascript
复制
@Entity
public class Bar {
    @Id
    @GeneratedValue
    private Integer id;
    private Boolean isSuccess;// 注意这是错误的命名
    private boolean isSend;// 注意这是错误的命名
    public Boolean getSuccess() {
        return isSuccess;
    }
    public void setSuccess(Boolean success) {
        isSuccess = success;
    }
    public boolean isSend() {
        return isSend;
    }
    public void setSend(boolean send) {
        isSend = send;
    }
}

其中,isSuccess使用的是包装类型Boolean,而isSend使用的是原生类型boolean,而getter,setter方法是使用Intellij IDEA自动生成的,布尔类型生成getter,setter方法时略微特殊,比如原生类型的getter方式是以is开头的。生成getter,setter方法之后,其实已经有点奇怪了,不急,继续下面的实验。

在数据库中,isSuccess被映射了 is_success,isSend被映射成了 is_send,这符合我们的预期。并且为了后续的实验,我们事先准备一条记录,用于后续的查询,在mysql的方言中,布尔类型被默认自动映射成byte,1代表ture,0代表false。

id

is_success

is_send

1

1

1

使用JdbcTemplate查询

代码语言:javascript
复制
public void test(String id) {
    RowMapper<Bar> barRowMapper = new BeanPropertyRowMapper<Bar>(Bar.class);
    Bar bar = jdbcTemplate.queryForObject("select * from bar where id = ?", new Object[]{id}, barRowMapper);
    System.out.println(bar);
}

JdbcTemplate提供了BeanPropertyRowMapper完成数据库到实体类的映射,事先我重写了Bar类的toString方法,调用 test(1)看看是否能成功映射。结果如下:

代码语言:javascript
复制
Bar{id=1, isSuccess=null, isSend=false}

数据库中是实际存在这样的字段,并且值都是true,而使用JdbcTemplate,却查询不到数据,而使用常规的命名方式命名则不会有这样的问题,这便是不遵循规范导致的问题。特别是在维护老旧代码时,如果发现有is开头的boolean值,需要额外地注意。

包装类型与原生类型

再回顾一下上述的demo,原生类型和包装类型都没有封装成功,isSuccess得到了一个null值,isSend得到了一个false值。后者足够引起我们的警惕,如果说前者会引起一个NullPointerExcepiton导致程序异常,还可以引起开发者的注意,而后者很有可能一直作为一个隐藏的bug,不被人所察觉,因为boolean的默认值为false。

在类变量中,也普遍提倡使用包装类型,而原生类型的不足之处是很明显的。以Integer num;字段为例,num=null代表的含义是num字段未被保存,未定义;而num=0代表的含义是明确的,数量为0。原生类型的表达能力有限。所以提倡在局部作用域的计算中使用原生类型,而在类变量中使用包装类型。

JavaBean规范

如今的微服务的时代,都是在聊架构,聊容器编排,竟然还有人聊JavaBean,但既然说到了规范,顺带提下。

先来做个选择题,以下选项中符合JavaBean命名规范的有哪些?:

代码语言:javascript
复制
A : ebook
B : eBook
C : Ebook
D : EBook

.

.

.

.

正确答案是:A,D

怎么样,符合你的预想吗?JavaBean规范并不是像很多人想的那样,首字母小写,之后的每一个单词首字母大写这样的驼峰命名法。正确的命名规范应该是:要么前两个字母都是小写,要么前两个字母都是大写。因为英文单词中有URL,USA这样固定形式的大写词汇,所以才有了这样的规范。特别警惕B那种形式,一些诸如sNo,eBook,eMail,cId这样的命名,都是不规范的。

由此引申出了getter,setter命名的规范,除了第一节中Boolean类型的特例之外,网上还有不少文章,强调了这样的概念:eBook对应的getter,setter应当为geteBook(),seteBook(),即当类变量的首字母是小写,而第二个字母是大写时,生成的getter,setter应当是(get/set)+类变量名。但上面已经介绍过了,eBook这样的变量命名本身就是不规范的,在不规范的变量命名下强调规范的getter,setter命名,出发点就错了。有兴趣的朋友可以在eclipse,intellij idea中试试,这几种规范/不规范的变量命名,各自对应的getter,setter方法是如何的。另外需要知晓一点,IDE提供的自动生成getter,setter的机制,以及lombok这类框架的机制,都有默认的规则,在与其他反射框架配合使用时,只有双方都遵循规范,才能够配合使用,而不能笃信框架。这一点上,有部分国产的框架工具做的并不是很好。

最后说一个和JavaBean相关的取值规范,在jsp的c标签,freemarker一类的模板语法,以及一些el表达式中,${student.name}并不是取的student的name字段,而是调用了student的getName方法,这也应当被注意,student.name如何找到对应的getter方法,需要解决上一段中提到的同样的问题,建议不确定的地方多测试,尽量采取稳妥的写法。

可能有人会觉得这样的介绍类似于“茴”字有几种写法,但笔者认为恰恰是这些小的规范,容易被人忽视,才更加需要被注意。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2017-09-25,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Kirito的技术分享 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Boolean变量名命名规范
    • 定义实体类
      • 使用JdbcTemplate查询
      • 包装类型与原生类型
      • JavaBean规范
      相关产品与服务
      容器服务
      腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档