首页  

java编码规范     所属分类 java 浏览量 1319
参考 Alibaba Java Coding Guidelines

https://github.com/alibaba/p3c

BLOCKER,CRITICAL,MAJOR

并发,集合,命名风格,常量定义, OOP规约,控制语句,异常处理,代码风格,注释等 



并发处理 1 [CRITICAL] 必须清理自定义的ThreadLocal变量,在 finally 块处理 2 [CRITICAL] 创建线程或线程池时指定有意义的名称,方便排查定位问题。 public class MyTaskThread extends Thread { public MyTaskThread(){ super.setName("MyTaskThread"); } } 3 [BLOCKER] 使用线程池,不建议在应用中显式创建线程 减少在创建和销毁线程上所消耗的时间以及系统资源开销 大量创建类线程 消耗完内存 过度切换 4 [BLOCKER] 线程池不要使用Executors去创建,而是通过ThreadPoolExecutor方式,明确线程池的运行规则,规避资源耗尽的风险。 Executors 返回的线程池对象的问题 1) FixedThreadPool 和 SingleThreadPool 最大请求队列长度为 Integer.MAX_VALUE.可能会堆积导致OOM 2) CachedThreadPool: 允许创建线程数为 Integer.MAX_VALUE. 可能会创建大量的线程,导致OOM 5 [CRITICAL] SimpleDataFormat非线程安全 使用DateUtils,推荐以下用法 private static final ThreadLocal df = new ThreadLocal() { @Override protected DateFormat initialValue() { return new SimpleDateFormat("yyyy-MM-dd"); } }; 6 [BLOCKER] Timer 和 ScheduledExecutorService 任务注意处理 异常 Timer和ScheduledExecutorService的区别 7 [MAJOR] 使用 CountDownLatch 每个线程退出时确保 调用 countDown 方法 8 [MAJOR] 避免 Random 实例被多线程使用,虽然该实例是线程安全的,但会因竞争同一 seed 导致性能下降。 JDK7 之后 可以直接使用 ThreadLocalRandom
集合处理 1 [CRITICAL] ArrayList 的 subList 结果不可强转成 ArrayList,会抛 ClassCastException 异 常,java.util.RandomAccessSubList cannot be cast to java.util.ArrayList。 subList 返回 ArrayList 的内部类 SubList, 是 ArrayList 的一个视图,对于 SubList 所有操作最终会反映到原列表上。 2 [CRITICAL] 在subList场景中,高度注意对原集合元素的增加或删除,均会导致子列表的遍 历、增加、删除产生 ConcurrentModificationException 异常。 3 [CRITICAL] 集合转数组使用集合的toArray(T[]array),传入类型一致且长度为 0 的空数组。 List list = new ArrayList(2); list.add("a"); list.add("b"); String[] array = new String[0]; array = list.toArray(array); the array into which the elements of this list are to be stored, if it is big enough; otherwise, a new array of the same runtime type is allocated for this purpose. 传入的数组容量够大,直接返回,否则新创建一个数组 4 [CRITICAL] Arrays.asList() 数组转换成集合,不能使用 add/remove/clear 等方法 ,否则 UnsupportedOperationException Arrays.asList 返回 Arrays 内部类,并没有实现集合的修改方法。 java.util.Arrays$ArrayList 包装了数组 , 是数组的视图 5 [BLOCKER] 不要在 foreach 循环 调用 remove/add 操作 list 遍历删除元素的正确做法 Iterator it = list.iterator(); while(it.hasNext()){ Integer item = it.next(); if (item.intValue() % 2 == 0) { it.remove(); } } 集合遍历删除注意点 6[MAJOR] 集合初始化时,指定集合初始值大小 说明:HashMap 使用 HashMap(int initialCapacity) 初始化
命名风格 1 [CRITICAL] 变量名不能以下划线或美元符号开始,也不能以下划线或美元符号结束 2 [MAJOR] 包名全部小写 , 类名使UpperCamelCase形式 , DO/BO/DTO/VO/AO/PO 等 全部大写 3 [CRITICAL] 方法名、参数名、成员变量、局部变量都统一使用lowerCamelCase风格 4 [CRITICAL] 常量命名全部大写,单词间用下划线隔开 5 [CRITICAL] 抽象类命名使用Abstract或Base开头;异常类命名使用Exception结尾; 6 [MAJOR] 测试类名以目标测试类名为前缀,以 Test 结尾 7 [MAJOR] 数组声明 ,中括号与类型在一起 int[] intArray; 8 [CRITICAL] POJO中布尔类型变量名不要加is前缀,否则部分框架序列化错误 9 [MAJOR] 包名统一使用小写,包名统一使用单数形式,类名可以使用复数形式 com.dyyx.CommUtils 10 [CRITICAL] 接口实现类 在接口类后面加Impl后缀 HelloImpl implements Hello CacheServiceImpl 实现 CacheService 接口 AbstractTranslator 实现 Translatable 接口 枚举类名加上 Enum 后缀,成员名全部大写,单词间用下划线隔开 枚举是特殊的常量类,且构造方法默认强制私有。 Service/DAO层方法命名规约 1) 获取单个对象的方法用 get 前缀 2) 获取多个对象的方法用 list 前缀 3) 获取统计值的方法用 count 前缀 4) 插入方法用 save/insert 前缀 5) 删除方法用 remove/delete 前缀 6) 修改的方法用 update/modify 前缀
常量定义 1 [MAJOR] 不要使用魔法值 2 [BLOCKER] 在long或者Long赋值时,数值后使用大写的L,小写容易跟数 字 1 搞混 Long a = 2L;
OOP规约 1 [CRITICAL] Object equals方法容易抛空指针异常 "test".equals(object); 推荐使用 java.util.Objects#equals 2 [BLOCKER] 所有包装类对象之间值的比较,全部使用equals方法 3 [MAJOR] 基本数据类型与包装数据类型的使用 POJO 类属性必须使用包装类型 RPC 方法的返回值和参数必须使用包装类型 所有的局部变量使用基本类型 4 [MAJOR] 定义 DO/DTO/VO 等 POJO 类时,不要设置默认值 5 [MAJOR] POJO 类必须写 toString 方法 6 [MAJOR] 字符串拼接,使用 StringBuilder 7 [MAJOR] 避免精度丢失,避免使用 BigDecimal(double) 把 double 转成 BigDecimal
控制语句 1 [CRITICAL] switch块,每个case要么通过continue/break/return等来终止,要么注释说明程序将继续执行到哪一个 case 为止; switch 块,必须包含一个 default 语句并放在最后 2 [BLOCKER] 在if/else/for/while/do语句中必须使用大括号,即使只有一行代码 if (condition) {statements;} 3 [MAJOR] 不要在条件判断中执行复杂语句,可将复杂逻辑判断的结果赋值给一个有意义的布尔变量名 说明:很多 if 语句内的逻辑表达式相当复杂,与、或、取反混合运算,甚至各种方法纵深调用,理解成 本非常高。如果赋值一个非常好理解的布尔变量名字,则是件令人爽心悦目的事情。 4 [Recommended] 避免采用反逻辑运算符 ! 取反逻辑不利于快速理解,推荐使用正向逻辑写法
异常处理 1 [CRITICAL] 事务代码 ,catch异常后,如果需要回滚事务,一定要手动回滚事务。 2 [CRITICAL] 不要在finally块中使用return try 块中的 return 语句执行后,并不马上返回,而是继续执行 finally 块中的语句, 如果此处存 在 return 语句,则在此直接返回,丢弃 try 块中的返回值 3 [MAJOR] 返回类型为基本类型,return 包装数据类型时,自动拆箱有可能产生 NPE public int xxx() { return Integer对象;} 可能 NPE
代码注释 1 [MAJOR] 类、类属性、类方法的注释必须使用Javadoc规范,使用/**内容*/格式,不得使用 // xxx 方式。 2 [MAJOR] 所有的抽象方法(包括接口中的方法)必须要用Javadoc注释、除了返回值、参数、异常说明外,还必须指出该方法做什么事情,实现什么功能。 对子类的实现要求,或者调用注意事项,请一并说明。 3 [MAJOR] 所有的类都必须添加创建者和创建日期。 4 [MAJOR] 方法内部单行注释,在被注释语句上方另起一行,使用//注释。方法内部多行注释 使用/* */注释,注意与代码对齐。 5 [CRITICAL] 所有的枚举类型字段必须要有注释,说明每个数据项的用途。
代码格式 1 [MAJOR] 单个方法的总行数不超过 80 行 除注释之外的方法签名、左右大括号、方法内代码、空行、回车及任何不可见字符的总行数不超过 80 行 其他 1 [MAJOR] 避免用Apache Beanutils进行属性copy Apache BeanUtils性能较差,可以使用其他方案比如Spring BeanUtils, Cglib BeanCopier。 2 [BLOCKER] 使用正则表达式时,利用预编译功能 不要在方法体内定义:Pattern pattern = Pattern.compile("xxx"); 3 [BLOCKER] 后台输送给页面的变量 $!{var} 注意加上感叹号 4 [MAJOR] Math.random() 返回 double 类型,取值范围[0,1) (可能为0,注意除零异常) 获取整数类型随机数,使用 Random 对象的 nextInt 或者 nextLong 方法 5 [BLOCKER] 获取当前毫秒数 System.currentTimeMillis(); 不要使用 new Date().getTime(); 获取更加精确的纳秒级时间 使用 System.nanoTime() 6 [CRITICAL] 日期格式化格式 yyyy 表示当天所在的年,而大写的 YYYY 代表是 week in which year (JDK7 之后引入), 当天所在的周属于的年份,一周从周日开始,周六结束, 只要本周跨年,返回的 YYYY 就是下一年 表示月份是大写的 M 表示分钟则是小写的 m 24 小时制的是大写的 H 12 小时制的则是小写的 h SSS 毫秒 new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); yyyy-MM-dd HH:mm:ss.SSS 7 [MAJOR] 及时清理不再使用的代码或配置信息

上一篇     下一篇
不要在finally块中使用return

jcmd PerfCounter 说明

集合遍历删除注意点

jvm热点线程定位

并发编程模型

slf4j为什么用{}而不是%s