本文参考自阿里孤尽老师的《码出高效代码》一书的第三章,为了节省大家学习时间,在这里对重要知识进行了总结,如果有知识点不明白的可以关注作者,找作者要相关的具体学习资料(免费送上)。
命名规约
命名符合本语言特性:每种编程语言都有各自的语言风格,如Java中,所有代码元素命名均不能以下画线或美元符号开始或结束。
命名体现代码元素特征:即从名字上即可知道代码元素的属性是什么(类、方法或常量等),有利于快速理清代码脉络。面向对象代码元素命名有大驼峰(UpperCameLCase)和小驼峰(upperCameLCase)命名两大类。
在Java推荐命名方式:
- 类名一般采用大驼峰+名词进行命名,如Object、String等。
- 方法名一般采用小驼峰+动词进行命名,如Object的wait()方法。
- 变量(参数、成员变量、局部变量等)命名采用小驼峰。
- 常量命名(局部常量除外)比较特殊,字母全部大写,单词之间用下画线连接,如MAX_COUNT。
- 包名统一使用小写,点分隔符之间有且仅有一个自然语义的英文单词,包名统一使用单数形式,但是类名如果有复数含义,则可以使用复数形式。
- 抽象类命名使用Abstract或Base开头。
- 异常类命名使用Exception结尾。
- 测试类命名以它要测试的类名开始,以Test结尾。
- 类型与中括号紧挨相连来定义数组。
- 枚举类名带上Enum后缀,枚举成员名称需要大写,单词间用下划线隔开。
- 禁止单字母变量命名。(循环index等变量除外)
- 禁止中英文结合命名。如DaZePromotion。
- 推荐全英文命名。alibaba、taobao、hangzhou等国家通用名词可以视同英文。推荐使用完整单词组合来命名,不要怕命名太长。
常量命名
全局常量指的是公开静态属性,使用public static final修饰。 命名方式:字母全部大写,单词之间用下划线连接。如:MAX_COUNT;类内常量是私有静态属性。使用private static final修饰。 命名方式:同上。局部常量分为方法常量和参数常量,前者是在方法或代码块中定义的常量,后者是在定义方法形参上,增加final标识,表示此值不能被修改。 命名方式:跟普通变量命名一样,采用小驼峰命名即可。常量是在作用域内保持不变的值,一般用final关键字修饰。按作用域划分可分为:全局常量、类内常量、局部常量。
public class Constant { //全局常量 public static final String GLOBAL_CONSTANT = "GLOBAL_CONSTANT"; //类内常量 public static final String CLASS_CONSTANT = "CLASS_CONSTANT"; /** * 局部常量示列方 * @param argConstant 方法常量 */ public void func1(final int argConstant){ //方法常量 final int methodConstant = 100; }}
禁止使用魔法值:
/** * 错误魔法值示例 * @param courseType 课程类型*/public void getCourse(Integer courseType){ if (courseType == 1){ System.out.println("Java"); }else if (courseType == 2){ System.out.println("C++"); }}
上述示列,1和2分别表示Java课程和C++课程,如果课程增多,这些魔法数字很容易记错,如果不小心搞错了,很容易造成故障。我们可以把这些魔法值定义成全局常量。这里我们使用Enum枚举类定义课程类型,示列代码如下:
public enum CourseTypeEnum{ JAVA_COURSE(1, "JAVA"), C_PLUS_PLUS_COURSE(2, "C++"); private int code; private String desc; CourseTypeEnum(int code, String desc) { this.code = code; this.desc = desc; } public int getCode() { return code; } public void setCode(int code) { this.code = code; } public String getDesc() { return desc; } public void setDesc(String desc) { this.desc = desc; }}
/** * 正确示例 * @param courseType 课程类型 */public void getCourse(Integer courseType){ if (courseType == CourseTypeEnum.JAVA_COURSE.getCode()){ System.out.println("Java"); }else if (courseType == CourseTypeEnum.C_PLUS_PLUS_COURSE.getCode()){ System.out.println("C++"); }}
利用预定义常量尽量避免魔法值的存在,有些公认的字面量是不需要预先定义的,如for(int i=0;...)这里的0可以直接使用。true或false也可以直接使用,但是如果具备了特殊的含义,就必须定义出有意义的常量名词,比如TreeMap源码中,用true和false表示红黑树的颜色。
private static final boolean RED = false;private static final boolean BLACK = true;
变量命名
变量指在程序运行过程中可以改变其值的量,包括成员变量和局部可变变量。
命名方式:小驼峰命名。注意:在POJO类中,针对布尔类的变量不要加is前缀,否则部分框架会引起序列化错误。在数据库建表中,推荐表达是与否采用is_xxx的命名方式,可以在中设置,将数据表中is_xxx字段映射到POJO类中的Xxx属性。如下所示:
缩进、空格与换行
- 缩进:有Tab键和空格缩进两种缩进方式。推荐空格缩进(4个空格键,因为Tab在不同编译器解析是不一样的,会导致视觉效果差)。大多数IDE默认为4个空格缩进,还有一部分编译器提供了Tab键与空格之间的转换设置(如IDEA、Eclipse)。
- 空格:用于分隔不同的编程元素。
- 换行:用于分隔相似、逻辑相聚、意思相近的代码段,使得代码布局变得更清晰。在方法定义后、属性定义与方法之间、不同逻辑、不同语义、不同业务代码之间都需要通过空行来分隔。
空格的使用约定如下:
任何二目、三目运算符的左右两边都必须加一个空格。注释的双斜线与注释内容有且仅有一个空格。方法参数在定义和传入时多,多个参数逗号后必须加空格。没有必要增加若干空格使变量的赋值等号与上一行对应位置的等号对齐。如果大括号内为空,则简洁地写{}即可,大括号中无须换行和空格。左右小括号与括号内部的相邻字符之间不要出现空格。左大括号前需要加空格。换行与高度
- 换行:约定单行字符不超过120个字符,超过则需要换行。
- 方法行数限制:单方法有效代码行数不超过80行。(具体可以见原文具体如何分析得出的)
换行时遵循如下原则:
- 第二行相对第一行缩进4个空格,从第三行开始,不再继续缩进。
- 运算符与下文一起换行。
- 方法调用的点符合与下文一起换行。
- 方法调用中的多个参数需要换行时,在逗号后换行。
- 在括号前不需要换行。
控制语句
在if、else、for、while、do-while等语句中必须使用大括号(即使只有一行代码)。在条件表达式中不允许有赋值操作,也不允许在判断表达式中出现复杂的逻辑逻辑。多层嵌套不能超过3层。避免采用反逻辑运算符。注释三要素
Nothing is strange:提倡写注释,然后把注释写得精简。 Less is more:尽量做代码自解释,精简注释。 Advance with the times:修改代码的同时修改注释。注释格式
Javadoc规范简单注释:分为单行注释和多行注释( 注释必须写在代码上方)。注释格式分为:Javadoc规范、简单注释。对枚举的注释是必须的,包括属性含义、注意事项、业务逻辑等。不可删除过时属性,对应属性上添加@Deprecated即可。
END
点赞+转发+关注,私信作者“读书笔记”即可获得BAT大厂面试资料、高级架构师VIP视频课程等高质量技术资料。