Java编程规约一

来自Alibaba的Java开发手册


前言

这些都是我阅读后,感觉容易忘记的知识点,然后在学习的过程中写下来,并附上自己的感受。另外,有些知识点,根据个人开发习惯,公司要求规范可能有所不同,需要结合实际情况灵活运用。


命名风格

稍微熟悉Java开发的道友都知道Java的基本命名规范如下:(1)可以 $ 、字母、下划线开头但不能数字开头。(2)后面的可以是数字、字母、下划线、美元符号。(3)不能是Java中的关键字。

而在实际开发中,为了团队各个成员能互相理解对方的代码,会约定一些规范以提高开发效率,在Alibaba中,部分规则如下:

(1)【强制】代码中的命名均不能以下划线或美元符号开始,也不能以下划线或美元符号结束。 

     反例:_name / $name _
     
(2)【强制】代码中的命名严禁使用拼音与英文混合的方式,更不允许直接使用中文的方式。 
     说明:正确的英文拼写和语法可以让阅读者易于理解,避免歧义。
     注意,即使纯拼音命名方式也要避免采用。对于这一点,可能有人不同意了吧,特别是对于英    
     语有点尴尬的童鞋(包括我233),不过,这确实是个不错的习惯,特别涉及一个较大的项目
     多人进行协作时,所以在以往的开发中,涉及一些不懂的词汇,我会选择百度翻译,或者可以
     直接下载一个有道词典。另一方面,这也间接 训练我们阅读国外一些大牛的代码的能力,毕竟
     他们的注释全是英文的。
     
     正例:alibaba / taobao / youku / hangzhou 等国际通用的名称,可视同英文。
    
     反例:DaZhePromotion [打折] / getPingfenByName() [评分] / int 某变量 = 3
    
(3)【强制】类名使用UpperCamelCase(即大骆驼拼写法或帕斯卡拼写法)风格,但以下情形
     例外:DO / BO / DTO / VO / AO/ PO / UID等。 意思就是,当类名是由多个英文单词复合而成
     时,每个单词的首字母需要我们大写,后边小写,其中,CamelCase 指“骆驼拼写法”。

	 正例:MarcoPolo / UserDO / XmlService / TcpUdpDeal / TaPromotion 
	 
	 反例:macroPolo / UserDo / XMLService / TCPUDPDeal / TAPromotion
	 
(4)【强制】方法名、参数名、成员变量、局部变量都统一使用lowerCamelCase风格,必须遵从
     驼峰形式,可以对照第三条理解。

     正例: localValue / getHttpMessage() / inputUserId
     
(5)【强制】常量命名全部大写,单词间用下划线隔开,力求语义表达完整清楚,不要嫌名字长。 

     正例:MAX_STOCK_COUNT 反例:MAX_COUNT
     
(6)【强制】抽象类命名使用Abstract或Base开头;异常类命名使用Exception结尾;测试类命名以
     它要测试的类的名称开始,以Test   结尾。这一点,个人认为也很重要,不说多人合作吧,就算是你
     一个人开发,当类逐渐增多时,有时写到后面,都不 知道前面哪个类是实现哪个功能的。之前,我
     在开发时,还有个弊病,就是测试类为了方便,总是命名为Test1,Test2......然后,时间一长,需要
     返工调试时,就懵逼了。

 (7)【强制】类型与中括号紧挨相连来 表示 数组。 
 
      正例: 定义整形数组 int[] arrayDemo;
      
      反例: 在 main 参数中,使用 String args[]来定义。
      
(8)【强制】POJO(Plain Ordinary Java Object,简单的Java对象,实际就是普通JavaBean)类中
     布尔类型的变量,都不要加is前缀,否则部分框架解析会引起序列化错误。 

     反例:定义为基本数据类型Boolean isDeleted的属性,它的方法也是isDeleted(),RPC框架在反向
     解析的时候,“误以为”对应的属性名称是deleted,导致属性获取不到,进而抛出异常。
    (RPC,Remote Procedure Call,远程过程调用,服务器之间的通信时都 是以字符串形式进行传送,
     此时将对象转为字符串的过程称为序列化,反之,称之为反序列)
     
(9)【强制】包名统一使用小写,点分隔符之间有且仅有一个自然语义的英语单词。包名统一使用单数形式,
     但是类名如果有复数含义,类名可以使用复数形式。 
     
     正例:应用工具类包名为com.alibaba.ai.util、类名为MessageUtils(此规则参考spring的框架结构)
     
(10)【强制】杜绝完全不规范的缩写,避免望文不知义。 反例:AbstractClass“缩写”命名成AbsClass;
      此类随意缩写严重降低了代码的可阅读性。

(11)【推荐】为了达到代码自解释的目标,任何定义编程元素在命名时使用尽量完整单词 组合来表达其意。 
 
      正例: 在 JDK 中,表达原子更新的类名为: AtomicReferenceFieldUpdater
       
      反例: 变量 int a 的随意命名方式。
       
(12)【推荐】如果模块、接口、类、方法使用了设计模式,在命名时需体现出具体模式。 
      说明:将设计模式体现在名字中,有利于阅读者快速理解架构设计理念。
       
       正例: public class OrderFactory; 
             public class LoginProxy; 
             public class ResourceObserver;
             
(13)【推荐】接口类中的方法和属性不要加任何修饰符号(public 也不要加),保持代码的简洁性,
      并加上有效的 Javadoc注释。尽量不要在接口里定义变量,如果一定要定义变量,肯定是与接口
      方法相关,并且是整个应用的基础常量。
      
     正例:接口方法签名void commit();
          接口基础常量String COMPANY = "alibaba"; 

     反例:接口方法定义public abstract void f(); 说明:JDK8中接口允许有默认实现,那么这个default方法,
     是对所有实现类都有价值的默认实现。
     
(14)接口和实现类的命名有两套规则:
      1)【强制】对于Service和DAO类,基于SOA的理念,暴露出来的服务一定是接口,内部的实现类用
         Impl的后缀与接口区别。
      
       正例:CacheServiceImpl实现CacheService接口。
       
      2) 【推荐】 如果是形容能力的接口名称,取对应的形容词为接口名(通常是–able的形式)。
      
       正例:AbstractTranslator实现 Translatable接口。
       
(15)【参考】枚举类名建议带上Enum后缀,枚举成员名称需要全大写,单词间用下划线隔开。 
      说明:枚举其实就是特殊的类,域成员均为常量,且构造方法被默认强制是私有。
      
       正例:枚举名字为ProcessStatusEnum的成员名称:SUCCESS / UNKNOWN_REASON。
       
(16)【参考】各层命名规约:

      A) Service/DAO层方法命名规约 :
       1) 获取单个对象的方法用get做前缀。
       2) 获取多个对象的方法用list做前缀,复数形式结尾如:listObjects。
       3) 获取统计值的方法用count做前缀。
       4) 插入的方法用save/insert做前缀。
       5) 删除的方法用remove/delete做前缀。
       6) 修改的方法用update做前缀。 

      B) 领域模型命名规约 :
       1) 数据对象:xxxDO,xxx即为数据表名。
       2) 数据传输对象:xxxDTO,xxx为业务领域相关的名称。
      3) 展示对象:xxxVO,xxx一般为网页名称。
      4) POJO是DO/DTO/BO/VO的统称,禁止命名成xxxPOJO。

常量定义

(1)【强制】不允许任何魔法值(即未经预先定义的常量)直接出现在代码中。

     反例:String key = "Id#taobao_" + tradeId; cache.put(key, value);
     
(2)【强制】在long或者Long赋值时,数值后使用大写的L,不能是小写的l,小写容易跟数字1混淆,造成误解。 
     说明:Long a = 2l; 写的是数字的21,还是Long型的2?
     
(3)【推荐】不要使用一个常量类维护所有常量,要按常量功能进行归类,分开维护。 
    说明:大而全的常量类,杂乱无章,使用查找功能才能定位到修改的常量,不利于理解和维护。
     
     正例:缓存相关常量放在类CacheConsts下;系统配置相关常量放在类ConfigConsts下。
     
(4)【推荐】常量的复用层次有五层:跨应用共享常量、应用内共享常量、子工程内共享常量、包内共享常量、
     类内共享常量。对于 :
    1) 跨应用共享常量:放置在二方库中,通常是client.jar中的constant目录下。 
    2) 应用内共享常量:放置在一方库中,通常是子模块中的constant目录下。 
    
       反例:易懂变量也要统一定义成应用内共享常量,两位攻城师在两个类中分别定义了表示“是”的变量:
       类A中:  public static final String YES = "yes";
       类B中:public static final String YES = "y"; A.YES.equals(B.YES),
       预期是true,但实际返回为false,导致线上问题。
       
    3) 子工程内部共享常量:即在当前子工程的constant目录下。
    4) 包内共享常量:即在当前包下单独的constant目录下。
    5) 类内共享常量:直接在类内部private static final定义。
    
(5)【推荐】如果变量值仅在一个固定范围内变化用enum类型来定义。 
     说明:如果存在名称之外的延伸属性应使用enum类型,下面正例中的数字就是延伸信息,表示一年中
     的第几个季节。 
     正例: 
     public enum SeasonEnum {
         SPRING(1), SUMMER(2), AUTUMN(3), WINTER(4); 
         private int seq; 
         SeasonEnum(int seq){ 
             this.seq = seq; 
         }
      }

代码格式

1、直接上图
在这里插入图片描述

其中,空格的设置是为了让同一份代码以不同软件打开时都能保持同一个格式,默认tab是8个字符,如果tab和空格混用,换一个工具打开时,可能就会变得乱七八糟,若直接用tab代替一个空格一个空格地敲则有如下的设置方法,以eclipse和idea为例子:

a. 在idea中,一个tab就已经默认为4个空格了,可以直接使用,具体设置方法如下,去掉use tab character,具体体验,大家可以勾上后对比看看。
在这里插入图片描述
b. 在eclipse中则如下:
在这里插入图片描述
上面是设置编写代码时的格式,格式化时还需要进一步设置,其中,我们可以通过new新建一个样式,然后在新建的样式中设置具体格式,最后应用上,这里,我直接修改现有的样式,即点击Edit:
在这里插入图片描述
第二步则是选择Spaces only,至此按Ctrl+shift+F进行格式化就不会产生错误了:
在这里插入图片描述

2、【强制】单行字符数限不超过 120 个,超出需要换行时 个,超出需要换行时 遵循如下原则:
 
1) 第二行相对一缩进 4个空格,从第三行开始不再继续缩进参考示例。
2) 运算符与下文一起换行。 
3) 方法调用的点符号与下文一起换行。 
4) 方法调用中的多个参数需要换行时,在逗号后进行。 
5) 在括号前不要换行,见反例。 

正例:
StringBuffer sb = new StringBuffer();
// 超过120个字符的情况下,换行缩进4个空格,点号和方法名称一起换行
sb.append("zi").append("xin")...
.append("huang")...
.append("huang")...
.append("huang");

反例:
StringBuffer sb = new StringBuffer();
// 超过120个字符的情况下,不要在括号前换行
sb.append("zi").append("xin")...append
("huang");

// 参数很多的方法调用可能超过120个字符,不要在逗号前换行
method(args1, args2, args3, ...
, argsX);

3、【强制】IDE的text file encoding设置为UTF-8; IDE中文件的换行符使用Unix格式,不要使用Windows格式。

这个地方 总是很容易出错,因为它总是容易被忽略。如果ide的文本格式不统一,那么将别人代码拷贝到你的idea中可能会产生乱码。

至于换行符,自己有过一次亲身经历,由于代码有点小小的错误,我直接将服务器上(Linux)的该代码文件拷贝到win上后,用文本工具打开后直接修改,然后再覆盖服务器上的文件,结果,程序跑起来后竟然报错了,查找多方面资料后,最后,在服务器上直接编译该文件时,终于找到原因,代码结尾处的大括号是有的,但却说缺少一个,而之所以报这样的错,是由于换行符的问题。

在windows下:\r\n代表换行,拆分两个代码是:回到行首+换到下一行 ,但是在linux下的区别是:只用\n即可以代表换行,将文件转为Unix格式后再覆盖服务器上文件,成功解决问题。


                                                                                                                                                                                              下一篇

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

legendaryhaha

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值