阿里巴巴Java代码规范

  • 1.及时清理不再使用的代码段或配置信息。
  • 2.不要在foreach循环里进行元素的remove/add操作,remove元素请使用Iterator方式。
  • 3. POJO类中的任何布尔类型的变量,都不要加is,否则部分框架解析会引起序列化错误
  • 4.在一个switch块内,每个case要么通过break/return等来终止,要么注释说明程序将继续执行到哪一个case为止;在一个switch块内,都必须包含一个default语句并且放在最后,即使它什么代码也没有。
  • 5.在if/else/for/while/do语句中必须使用大括号,即使只有一行代码,避免使用下面的形式:if (condition) statements;
  • 6.在subList场景中,高度注意对原列表的修改,会导致子列表的遍历、增加、删除均产生ConcurrentModificationException异常。
  • 7.POJO类必须写toString方法。使用工具类source> generate toString时,如果继承了另一个POJO类,注意在前面加一下super.toString。
  • 8.线程池不允许使用Executors去创建,而是通过ThreadPoolExecutor的方式,这样的处理方式让写的同学更加明确线程池的运行规则,规避资源耗尽的风险。
  • 9.单个方法的总行数不超过80行。
  • 10.集合初始化时,指定集合初始值大小。
  • 11.测试类命名以它要测试的类的名称开始,以Test结尾
  • 12.不允许任何魔法值(即未经定义的常量)直接出现在代码中。
  • 13. 线程资源必须通过线程池提供,不允许在应用中自行显式创建线程。
  • 14.后台输送给页面的变量必须加感叹号,${var}——中间加感叹号!。
  • 15. 创建线程或线程池时请指定有意义的线程名称,方便出错时回溯。创建线程池的时候请使用带ThreadFactory的构造函数,并且提供自定义ThreadFactory实现或者使用第三方实现。
  • 1.避免采用取反逻辑运算符。
  • 17.类、类属性、类方法的注释必须使用javadoc规范,使用/**内容*/格式,不得使用//xxx方式和/*xxx*/方式。
  • 18.循环体内,字符串的联接方式,使用StringBuilder的append方法进行扩展。
  • 19.关于基本数据类型与包装数据类型的使用标准
  • 20.iBATIS自带的queryForList(String statementName,int start,int size)不推荐使用
  • 21.常量命名应该全部大写,单词间用下划线隔开,力求语义表达完整清楚,不要嫌名字长
  • 22.所有编程相关的命名均不能以下划线或美元符号开始
  • 23.包名统一使用小写,点分隔符之间有且仅有一个自然语义的英语单词。包名统一使用单数形式,但是类名如果有复数含义,类名可以使用复数形式
  • 24.ArrayList的subList结果不可强转成ArrayList,否则会抛出ClassCastException异常。
  • 25. 类名使用UpperCamelCase风格,必须遵从驼峰形式,但以下情形例外:(领域模型的相关命名)DO / BO / DTO / VO / DAO
  • 26.使用工具类Arrays.asList()把数组转换成集合时,不能使用其修改集合相关的方法,它的add/remove/clear方法会抛出UnsupportedOperationException异常。
  • 27.多线程并行处理定时任务时,Timer运行多个TimeTask时,只要其中之一没有捕获抛出的异常,其它任务便会自动终止运行,使用ScheduledExecutorService则没有这个问题。
  • 28.避免用Apache Beanutils进行属性的copy。
  • 29.日期格式化字符串[%s]使用错误,应注意使用小写‘y’表示当天所在的年,大写‘Y’代表week in which year。
  • 30.返回类型为基本数据类型,return包装数据类型的对象时,自动拆箱有可能产生NPE
  • 31.Map/Set的key为自定义对象时,必须重写hashCode和equals。
  • 32.在使用正则表达式时,利用好其预编译功能,可以有效加快正则匹配速度。
  • 33.获取当前毫秒数:System.currentTimeMillis(); 而不是new Date().getTime();
  • 34.SimpleDateFormat 是线程不安全的类,一般不要定义为static变量,如果定义为static,必须加锁,或者使用DateUtils工具类。
  • 35.所有的抽象方法(包括接口中的方法)必须要用javadoc注释、除了返回值、参数、异常说明外,还必须指出该方法做什么事情,实现什么功能。
  • 36.方法内部单行注释,在被注释语句上方另起一行,使用//注释。方法内部多行注释使用/* */注释。注意与代码对齐。
  • 37.对于Service和DAO类,基于SOA的理念,暴露出来的服务一定是接口,内部的实现类用Impl的后缀与接口区别
  • 38.不能使用过时的类或方法。
  • 39.避免通过一个类的对象引用访问此类的静态变量或静态方法,无谓增加编译器解析成本,直接用类名来访问即可。
  • 40.注意 Math.random() 这个方法返回是double类型,注意取值的范围[0,1)(能够取到零值,注意除零异常),如果想获取整数类型的随机数,不要将x放大10的若干倍然后取整,直接使用Random对象的nextInt或者nextLong方法。
  • 41.避免Random实例被多线程使用,虽然共享该实例是线程安全的,但会因竞争同一seed 导致的性能下降。说明:Random实例包括java.util.Random 的实例或者 Math.random()的方式。
  • 42. 必须回收自定义的ThreadLocal变量,尤其在线程池场景下,线程经常会被复用,如果不清理自定义的 ThreadLocal变量,可能会影响后续业务逻辑和造成内存泄露等问题。尽量在代理中使用try-finally块进行回收。
  • 43.所有的类都必须添加创建者信息。
  • 44.定义DO/DTO/VO等POJO类时,不要加任何属性默认值。
  • 45.long或者Long初始赋值时,必须使用大写的L,不能是小写的l,小写容易跟数字1混淆,造成误解。
  • 46.事务场景中,抛出异常被catch后,如果需要回滚,一定要手动回滚事务。
  • 47.异常类命名使用Exception结尾
  • 48.使用集合转数组的方法,必须使用集合的toArray(T[] array),传入的是类型完全一样的数组,大小就是list.size()
  • 49.除常用方法(如getXxx/isXxx)等外,不要在条件判断中执行复杂的语句,将复杂逻辑判断的结果赋值给一个有意义的布尔变量,以提高可读性。
  • 50.Object的equals方法容易抛空指针异常,应使用常量或确定有值的对象来调用equals。
  • 51.所有的覆写方法,必须加@Override注解。
  • 52.抽象类命名使用Abstract或Base开头
  • 53.中括号是数组类型的一部分,数组定义如下:String[] args
  • 54.使用CountDownLatch进行异步转同步操作,每个线程退出前必须调用countDown方法,线程执行代码注意catch异常,确保countDown方法可以执行,避免主线程无法执行至await方法,直到超时才返回结果。
  • 55. 方法名、参数名、成员变量、局部变量都统一使用lowerCamelCase,必须遵从驼峰形式
  • 56. 不能在finally块中使用return,finally块中的return返回后方法结束执行,不会再执行try块中的return语句。
  • 57.所有的包装类对象之间值的比较,全部使用equals方法比较。
  • 58. 所有的枚举类型字段必须要有注释,说明每个数据项的用途。

阿里巴巴Java开发手册(华山版):https://github.com/JackWei1996/p3c/blob/master/%E9%98%BF%E9%87%8C%E5%B7%B4%E5%B7%B4Java%E5%BC%80%E5%8F%91%E6%89%8B%E5%86%8C%EF%BC%88%E5%8D%8E%E5%B1%B1%E7%89%88%EF%BC%89.pdf

1.及时清理不再使用的代码段或配置信息。

NameRemoveCommentedCodeRuleSeverityMajorMessage及时清理不再使用的代码段或配置信息。Description说明:对于垃圾代码或过时配置,坚决清理干净,避免程序过度臃肿,代码冗余。ExamplesPositive example: For codes which are temporarily removed and likely to be reused, use /// to add a reasonable note.public static void hello() {/// Business is stopped temporarily by the owner.// Business business = new Business();// business.active();System.out.println("it's finished");
}

2.不要在foreach循环里进行元素的remove/add操作,remove元素请使用Iterator方式。

NameDontModifyInForeachCircleRuleSeverityBlockerMessage不要在foreach循环里进行元素的remove/add操作,remove元素请使用Iterator方式。ExamplesNegative example:   List<String> originList = new ArrayList<String>();originList.add("22");for (String item : originList) { //warnlist.add("bb");}
Positive example: Iterator<Integer> it=b.iterator();      while(it.hasNext()){                      Integer temp =  it.next();             if (delCondition) {it.remove();}}   

3. POJO类中的任何布尔类型的变量,都不要加is,否则部分框架解析会引起序列化错误

NameBooleanPropertyShouldNotStartWithIsRuleSeverityCriticalMessagePOJO类中的任何布尔类型的变量,都不要加is,否则部分框架解析会引起序列化错误Examplespublic class DemoDO{Boolean success;Boolean delete;
}

4.在一个switch块内,每个case要么通过break/return等来终止,要么注释说明程序将继续执行到哪一个case为止;在一个switch块内,都必须包含一个default语句并且放在最后,即使它什么代码也没有。

NameSwitchStatementRuleSeverityCriticalMessage在一个switch块内,每个case要么通过break/return等来终止,要么注释说明程序将继续执行到哪一个case为止;在一个switch块内,都必须包含一个default语句并且放在最后,即使它什么代码也没有。Examplesswitch (x) {case 1:break;case 2:break;default:
}

5.在if/else/for/while/do语句中必须使用大括号,即使只有一行代码,避免使用下面的形式:if (condition) statements;

NameNeedBraceRuleSeverityBlockerMessage在if/else/for/while/do语句中必须使用大括号,即使只有一行代码,避免使用下面的形式:if (condition) statements;Examplesif (flag) {System.out.println("hello world");
}

6.在subList场景中,高度注意对原列表的修改,会导致子列表的遍历、增加、删除均产生ConcurrentModificationException异常。

NameConcurrentExceptionWithModifyOriginSubListRuleSeverityCriticalMessage在subList场景中,高度注意对原列表的修改,会导致子列表的遍历、增加、删除均产生ConcurrentModificationException异常。ExamplesNegative example:                List<String> originList = new ArrayList<String>();originList.add("22");List<String> subList = originList.subList(0, 1);//warnoriginList.add("22");

7.POJO类必须写toString方法。使用工具类source> generate toString时,如果继承了另一个POJO类,注意在前面加一下super.toString。

NamePojoMustOverrideToStringRuleSeverityMajorMessagePOJO类必须写toString方法。使用工具类source> generate toString时,如果继承了另一个POJO类,注意在前面加一下super.toString。Description说明:在方法执行抛出异常时,可以直接调用POJO的toString()方法打印其属性值,便于排查问题。Examplespublic class ToStringDemo extends Super{private String secondName;@Overridepublic String toString() {return super.toString() + "ToStringDemo{" + "secondName='" + secondName + '\'' + '}';}}class Super {private String firstName;@Overridepublic String toString() {return "Super{" + "firstName=" + firstName + '\'' + '}';}}   

8.线程池不允许使用Executors去创建,而是通过ThreadPoolExecutor的方式,这样的处理方式让写的同学更加明确线程池的运行规则,规避资源耗尽的风险。

NameThreadPoolCreationRuleSeverityBlockerMessage线程池不允许使用Executors去创建,而是通过ThreadPoolExecutor的方式,这样的处理方式让写的同学更加明确线程池的运行规则,规避资源耗尽的风险。Description说明:Executors各个方法的弊端:1)newFixedThreadPool和newSingleThreadExecutor:主要问题是堆积的请求处理队列可能会耗费非常大的内存,甚至OOM。2)newCachedThreadPool和newScheduledThreadPool:主要问题是线程数最大数是Integer.MAX_VALUE,可能会创建数量非常多的线程,甚至OOM。ExamplesPositive example 1://org.apache.commons.lang3.concurrent.BasicThreadFactoryScheduledExecutorService executorService = new ScheduledThreadPoolExecutor(1,new BasicThreadFactory.Builder().namingPattern("example-schedule-pool-%d").daemon(true).build());
Positive example 2:ThreadFactory namedThreadFactory = new ThreadFactoryBuilder().setNameFormat("demo-pool-%d").build();//Common Thread PoolExecutorService pool = new ThreadPoolExecutor(5, 200,0L, TimeUnit.MILLISECONDS,new LinkedBlockingQueue<Runnable>(1024), namedThreadFactory, new ThreadPoolExecutor.AbortPolicy());pool.execute(()-> System.out.println(Thread.currentThread().getName()));pool.shutdown();//gracefully shutdown
Positive example 3:<bean id="userThreadPool"class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor"><property name="corePoolSize" value="10" /><property name="maxPoolSize" value="100" /><property name="queueCapacity" value="2000" /><property name="threadFactory" value= threadFactory /><property name="rejectedExecutionHandler"><ref local="rejectedExecutionHandler" /></property></bean>//in codeuserThreadPool.execute(thread);

9.单个方法的总行数不超过80行。

NameMethodTooLongRuleSeverityMajorMessage单个方法的总行数不超过80行。Description说明:包括方法签名、结束右大括号、方法内代码、注释、空行、回车及任何不可见字符的总行数不超过80行。

10.集合初始化时,指定集合初始值大小。

NameCollectionInitShouldAssignCapacityRuleSeverityMajorMessage集合初始化时,指定集合初始值大小。Description说明:HashMap使用如下构造方法进行初始化,如果暂时无法确定集合大小,那么指定默认值(16)即可。ExamplesNegative example:   Map<String, String> map = new HashMap<String, String>();
Positive example: Map<String, String> map = new HashMap<String, String>(16);

11.测试类命名以它要测试的类的名称开始,以Test结尾

NameTestClassShouldEndWithTestNamingRuleSeverityMajorMessage测试类命名以它要测试的类的名称开始,以Test结尾Examplespublic class DemoTest {}

12.不允许任何魔法值(即未经定义的常量)直接出现在代码中。

NameUndefineMagicConstantRuleSeverityMajorMessage不允许任何魔法值(即未经定义的常量)直接出现在代码中。ExamplesNegative example://Magic values, except for predefined, are forbidden in coding.if (key.equals("Id#taobao_1")) {//...}
Positive example:String KEY_PRE = "Id#taobao_1";  if (KEY_PRE.equals(key)) {//...}   

13. 线程资源必须通过线程池提供,不允许在应用中自行显式创建线程。

NameAvoidManuallyCreateThreadRuleSeverityCriticalMessage线程资源必须通过线程池提供,不允许在应用中自行显式创建线程。Description说明:使用线程池的好处是减少在创建和销毁线程上所花的时间以及系统资源的开销,解决资源不足的问题。如果不使用线程池,有可能造成系统创建大量同类线程而导致消耗完内存或者“过度切换”的问题。ExamplesThreadFactory namedThreadFactory = new ThreadFactoryBuilder().setNameFormat("demo-pool-%d").build();ExecutorService singleThreadPool = new ThreadPoolExecutor(1, 1,0L, TimeUnit.MILLISECONDS,new LinkedBlockingQueue<Runnable>(1024), namedThreadFactory, new ThreadPoolExecutor.AbortPolicy());singleThreadPool.execute(()-> System.out.println(Thread.currentThread().getName()));singleThreadPool.shutdown();   

14.后台输送给页面的变量必须加感叹号,${var}——中间加感叹号!。

NameUseQuietReferenceNotationRuleSeverityMajorMessage后台输送给页面的变量必须加感叹号,${var}——中间加感叹号!。Description说明:如果var=null或者不存在,那么${var}会直接显示在页面上。Examples<input type="text" name="email" value="$!email"/><input type="text" name="email" value="$!{email}"/>   

15. 创建线程或线程池时请指定有意义的线程名称,方便出错时回溯。创建线程池的时候请使用带ThreadFactory的构造函数,并且提供自定义ThreadFactory实现或者使用第三方实现。

NameThreadShouldSetNameRuleSeverityCriticalMessage创建线程或线程池时请指定有意义的线程名称,方便出错时回溯。创建线程池的时候请使用带ThreadFactory的构造函数,并且提供自定义ThreadFactory实现或者使用第三方实现。ExamplesThreadFactory namedThreadFactory = new ThreadFactoryBuilder().setNameFormat("demo-pool-%d").build();ExecutorService singleThreadPool = new ThreadPoolExecutor(1, 1,0L, TimeUnit.MILLISECONDS,new LinkedBlockingQueue<Runnable>(1024), namedThreadFactory, new ThreadPoolExecutor.AbortPolicy());singleThreadPool.execute(()-> System.out.println(Thread.currentThread().getName()));singleThreadPool.shutdown();
public class TimerTaskThread extends Thread {public TimerTaskThread(){super.setName("TimerTaskThread"); …}

1.避免采用取反逻辑运算符。

NameAvoidNegationOperatorRuleSeverityMajorMessage避免采用取反逻辑运算符。Description说明: 取反逻辑不利于快速理解,并且取反逻辑写法必然存在对应的正向逻辑写法。ExamplesNegative example:// Use `if (!(x >= 628))` to represent that x is less than 628.if (!(x >= 628)) {// ...}
Positive example:// Use `if (x < 628)` to represent that x is less than 628.if (x < 628)) {// ...}

17.类、类属性、类方法的注释必须使用javadoc规范,使用/*内容/格式,不得使用//xxx方式和/xxx/方式。

NameCommentsMustBeJavadocFormatRuleSeverityMajorMessage类、类属性、类方法的注释必须使用javadoc规范,使用/**内容*/格式,不得使用//xxx方式和/*xxx*/方式。Description说明:在IDE编辑窗口中,javadoc方式会提示相关注释,生成javadoc可以正确输出相应注释;在IDE中,工程调用方法时,不进入方法即可悬浮提示方法、参数、返回值的意义,提高阅读效率。Examples/*** * XXX class function description.**/public class XxClass implements Serializable {private static final long serialVersionUID = 113323427779853001L;/*** id*/private Long id;/*** title*/private String title;/*** find by id* * @param ruleId rule id* @param page start from 1* @return Result<Xxxx>*/public Result<Xxxx> funcA(Long ruleId, Integer page) {return null;}}

18.循环体内,字符串的联接方式,使用StringBuilder的append方法进行扩展。

NameStringConcatRuleSeverityMajorMessage循环体内,字符串的联接方式,使用StringBuilder的append方法进行扩展。Description说明:反编译出的字节码文件显示每次循环都会new出一个StringBuilder对象,然后进行append操作,最后通过toString方法返回String对象,造成内存资源浪费。ExamplesNegative example:String result;for (String string : tagNameList) {result = result + string;}
Positive example:StringBuilder stringBuilder = new StringBuilder();for (String string : tagNameList) {stringBuilder.append(string);}String result = stringBuilder.toString();

19.关于基本数据类型与包装数据类型的使用标准

NamePojoMustUsePrimitiveFieldRuleSeverityMajorMessage关于基本数据类型与包装数据类型的使用标准如下:1) 所有的POJO类属性必须使用包装数据类型。2) RPC方法的返回值和参数必须使用包装数据类型。3) 所有的局部变量推荐使用基本数据类型。Description说明:POJO类属性没有初值是提醒使用者在需要使用时,必须自己显式地进行赋值,任何NPE问题,或者入库检查,都由使用者来保证。Examplespublic class DemoDO {String str;Integer a;
}

20.iBATIS自带的queryForList(String statementName,int start,int size)不推荐使用

NameIbatisMethodQueryForListRuleSeverityMajorMessageiBATIS自带的queryForList(String statementName,int start,int size)不推荐使用

21.常量命名应该全部大写,单词间用下划线隔开,力求语义表达完整清楚,不要嫌名字长

NameConstantFieldShouldBeUpperCaseRuleSeverityCriticalMessage常量命名应该全部大写,单词间用下划线隔开,力求语义表达完整清楚,不要嫌名字长Examplespublic class ConstantNameDemo {/*** max stock count*/public static final Long MAX_STOCK_COUNT = 50000L;   

22.所有编程相关的命名均不能以下划线或美元符号开始

NameAvoidStartWithDollarAndUnderLineNamingRuleSeverityCriticalMessage所有编程相关的命名均不能以下划线或美元符号开始

23.包名统一使用小写,点分隔符之间有且仅有一个自然语义的英语单词。包名统一使用单数形式,但是类名如果有复数含义,类名可以使用复数形式

NamePackageNamingRuleSeverityMajorMessage包名统一使用小写,点分隔符之间有且仅有一个自然语义的英语单词。包名统一使用单数形式,但是类名如果有复数含义,类名可以使用复数形式Examplescom.alibaba.mpp.util / com.taobao.tddl.domain.dto   

24.ArrayList的subList结果不可强转成ArrayList,否则会抛出ClassCastException异常。

NameClassCastExceptionWithSubListToArrayListRuleSeverityCriticalMessageArrayList的subList结果不可强转成ArrayList,否则会抛出ClassCastException异常。Description说明:禁止强转,如果需要用到集合特性方法,请新建一个集合,然后置入sublist,new 集合(sublist结果)。ExamplesNegative example:List<String> list = new ArrayList<String>();list.add("22");//warnList<String> test = (ArrayList<String>) list.subList(0, 1);
Positive example:List<String> list2 = new ArrayList<String>(list.subList(0, 1));   

25. 类名使用UpperCamelCase风格,必须遵从驼峰形式,但以下情形例外:(领域模型的相关命名)DO / BO / DTO / VO / DAO

NameClassNamingShouldBeCamelRuleSeverityMajorMessage类名使用UpperCamelCase风格,必须遵从驼峰形式,但以下情形例外:(领域模型的相关命名)DO / BO / DTO / VO / DAO

26.使用工具类Arrays.asList()把数组转换成集合时,不能使用其修改集合相关的方法,它的add/remove/clear方法会抛出UnsupportedOperationException异常。

NameUnsupportedExceptionWithModifyAsListRuleSeverityCriticalMessage使用工具类Arrays.asList()把数组转换成集合时,不能使用其修改集合相关的方法,它的add/remove/clear方法会抛出UnsupportedOperationException异常。ExamplesPositive example:List<String> t   = Arrays.asList("a","b","c"); //warnt.add("22");//warnt.remove("22");//warnt.clear();   

27.多线程并行处理定时任务时,Timer运行多个TimeTask时,只要其中之一没有捕获抛出的异常,其它任务便会自动终止运行,使用ScheduledExecutorService则没有这个问题。

NameAvoidUseTimerRuleSeverityBlockerMessage多线程并行处理定时任务时,Timer运行多个TimeTask时,只要其中之一没有捕获抛出的异常,其它任务便会自动终止运行,使用ScheduledExecutorService则没有这个问题。Examples//org.apache.commons.lang3.concurrent.BasicThreadFactoryScheduledExecutorService executorService = new ScheduledThreadPoolExecutor(1,new BasicThreadFactory.Builder().namingPattern("example-schedule-pool-%d").daemon(true).build());executorService.scheduleAtFixedRate(new Runnable() {@Overridepublic void run() {//do something}},initialDelay,period, TimeUnit.HOURS);   

28.避免用Apache Beanutils进行属性的copy。

NameAvoidApacheBeanUtilsCopyRuleSeverityBlockerMessage避免用Apache Beanutils进行属性的copy。Description说明:Apache BeanUtils性能较差,可以使用其他方案比如Spring BeanUtils, Cglib BeanCopier。ExamplesTestObject a = new TestObject();TestObject b = new TestObject();a.setX(b.getX());a.setY(b.getY());

29.日期格式化字符串[%s]使用错误,应注意使用小写‘y’表示当天所在的年,大写‘Y’代表week in which year。

NameUseRightCaseForDateFormatRuleSeverityCriticalMessage日期格式化字符串[%s]使用错误,应注意使用小写‘y’表示当天所在的年,大写‘Y’代表week in which year。Description日期格式化时,yyyy表示当天所在的年,而大写的YYYY代表是week in which year(JDK7之后引入的概念),意思是当天所在的周属于的年份,一周从周日开始,周六结束,只要本周跨年,返回的YYYY就是下一年。ExamplesNegative example:SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Positive example:SimpleDateFormat format = new SimpleDateFormat("YYYY-mm-dd HH:mm:ss");   

30.返回类型为基本数据类型,return包装数据类型的对象时,自动拆箱有可能产生NPE

NameMethodReturnWrapperTypeRuleSeverityMajorMessage返回类型为基本数据类型,return包装数据类型的对象时,自动拆箱有可能产生NPEExamplespublic int method() {Integer a = null;return a;}   

31.Map/Set的key为自定义对象时,必须重写hashCode和equals。

NameMapOrSetKeyShouldOverrideHashCodeEqualsRuleSeverityCriticalMessageMap/Set的key为自定义对象时,必须重写hashCode和equals。Description关于hashCode和equals的处理,遵循如下规则:1) 只要重写equals,就必须重写hashCode。2) 因为Set存储的是不重复的对象,依据hashCode和equals进行判断,所以Set存储的对象必须重写这两个方法。3) 如果自定义对象做为Map的键,那么必须重写hashCode和equals。

32.在使用正则表达式时,利用好其预编译功能,可以有效加快正则匹配速度。

NameAvoidPatternCompileInMethodRuleSeverityBlockerMessage在使用正则表达式时,利用好其预编译功能,可以有效加快正则匹配速度。Description说明:不要在方法体内定义:Pattern pattern = Pattern.compile(规则);Examplespublic class XxxClass {// Use precompileprivate static Pattern NUMBER_PATTERN = Pattern.compile("[0-9]+");public Pattern getNumberPattern() {// Avoid use Pattern.compile in method body.Pattern localPattern = Pattern.compile("[0-9]+");return localPattern;}}   

33.获取当前毫秒数:System.currentTimeMillis(); 而不是new Date().getTime();

NameAvoidNewDateGetTimeRuleSeverityBlockerMessage获取当前毫秒数:System.currentTimeMillis(); 而不是new Date().getTime();Description说明:如果想获取更加精确的纳秒级时间值,用System.nanoTime。在JDK8中,针对统计时间等场景,推荐使用Instant类。Examplespublic class TimeMillisDemo {public static void main(String args[]) {// Positive example:long a = System.currentTimeMillis();// Negative example:long b = new Date().getTime();System.out.println(a);System.out.println(b);}}   

34.SimpleDateFormat 是线程不安全的类,一般不要定义为static变量,如果定义为static,必须加锁,或者使用DateUtils工具类。

NameAvoidCallStaticSimpleDateFormatRuleSeverityCriticalMessageSimpleDateFormat 是线程不安全的类,一般不要定义为static变量,如果定义为static,必须加锁,或者使用DateUtils工具类。Description说明:如果是JDK8的应用,可以使用instant代替Date,LocalDateTime代替Calendar,DateTimeFormatter代替SimpleDateFormat,官方给出的解释:simple beautiful strong immutable thread-safe。ExamplesPositive example 1:private static final String FORMAT = "yyyy-MM-dd HH:mm:ss";public String getFormat(Date date){SimpleDateFormat dateFormat = new SimpleDateFormat(FORMAT);return sdf.format(date);}
Positive example 2:private static final SimpleDateFormat SIMPLE_DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");public void getFormat(){synchronized (sdf){sdf.format(new Date());….;}
Positive example 3:private static final ThreadLocal<DateFormat> DATE_FORMATTER = new ThreadLocal<DateFormat>() {@Overrideprotected DateFormat initialValue() {return new SimpleDateFormat("yyyy-MM-dd");}};   

35.所有的抽象方法(包括接口中的方法)必须要用javadoc注释、除了返回值、参数、异常说明外,还必须指出该方法做什么事情,实现什么功能。

NameAbstractMethodOrInterfaceMethodMustUseJavadocRuleSeverityMajorMessage所有的抽象方法(包括接口中的方法)必须要用javadoc注释、除了返回值、参数、异常说明外,还必须指出该方法做什么事情,实现什么功能。Description说明:如有实现和调用注意事项,请一并说明。Examples/*** fetch data by rule id* * @param ruleId rule id* @param page page number* @param jsonContext json format context* @return Result<XxxxDO>*/Result<XxxxDO> fetchDataByRuleId(Long ruleId, Integer page, String jsonContext);   

36.方法内部单行注释,在被注释语句上方另起一行,使用//注释。方法内部多行注释使用/* */注释。注意与代码对齐。

NameAvoidCommentBehindStatementRuleSeverityMajorMessage方法内部单行注释,在被注释语句上方另起一行,使用//注释。方法内部多行注释使用/* */注释。注意与代码对齐。Examplespublic void method() {// Put single line comment above code. (Note: align '//' comment with code)int a = 3;/*** Some description about follow code. (Note: align '/**' comment with code)*/int b = 4;}   

37.对于Service和DAO类,基于SOA的理念,暴露出来的服务一定是接口,内部的实现类用Impl的后缀与接口区别

NameServiceOrDaoClassShouldEndWithImplRuleSeverityCriticalMessage对于Service和DAO类,基于SOA的理念,暴露出来的服务一定是接口,内部的实现类用Impl的后缀与接口区别Examplespublic interface DemoService{void f();}public class DemoServiceImpl implements DemoService {@Overridepublic void f(){System.out.println("hello world");}}   

38.不能使用过时的类或方法。

NameAvoidUseDeprecationRuleSeverityCriticalMessage不能使用过时的类或方法。Description说明:java.net.URLDecoder 中的方法decode(String encodeStr) 这个方法已经过时,应该使用双参数decode(String source, String encode)。接口提供方既然明确是过时接口,那么有义务同时提供新的接口;作为调用方来说,有义务去考证过时方法的新实现是什么。

39.避免通过一个类的对象引用访问此类的静态变量或静态方法,无谓增加编译器解析成本,直接用类名来访问即可。

NameAvoidAccessStaticViaInstanceRuleSeverityBlockerMessage避免通过一个类的对象引用访问此类的静态变量或静态方法,无谓增加编译器解析成本,直接用类名来访问即可。

40.注意 Math.random() 这个方法返回是double类型,注意取值的范围[0,1)(能够取到零值,注意除零异常),如果想获取整数类型的随机数,不要将x放大10的若干倍然后取整,直接使用Random对象的nextInt或者nextLong方法。

NameAvoidMissUseOfMathRandomRuleSeverityMajorMessage注意 Math.random() 这个方法返回是double类型,注意取值的范围[0,1)(能够取到零值,注意除零异常),如果想获取整数类型的随机数,不要将x放大10的若干倍然后取整,直接使用Random对象的nextInt或者nextLong方法。ExamplesNegative example:Long randomLong =(long) (Math.random() * 10);
Positive example:Long randomLong = new Random().nextLong();   

41.避免Random实例被多线程使用,虽然共享该实例是线程安全的,但会因竞争同一seed 导致的性能下降。说明:Random实例包括java.util.Random 的实例或者 Math.random()的方式。

NameAvoidConcurrentCompetitionRandomRuleSeverityMajorMessage避免Random实例被多线程使用,虽然共享该实例是线程安全的,但会因竞争同一seed 导致的性能下降。说明:Random实例包括java.util.Random 的实例或者 Math.random()的方式。ExamplesPositive example 1:/*** @author caikang* @date 2017/04/07*/public class RandomInThread extends Thread {private Random random = new Random();@Overridepublic void run() {long t = random.nextLong();}}
Positive example 2:/*** @author caikang* @date 2017/04/07*/public class RandomInThread extends Thread {private Random random = ThreadLocalRandom.current();@Overridepublic void run() {long t = random.nextLong();}}   

42. 必须回收自定义的ThreadLocal变量,尤其在线程池场景下,线程经常会被复用,如果不清理自定义的 ThreadLocal变量,可能会影响后续业务逻辑和造成内存泄露等问题。尽量在代理中使用try-finally块进行回收。

NameThreadLocalShouldRemoveRuleSeverityCriticalMessage必须回收自定义的ThreadLocal变量,尤其在线程池场景下,线程经常会被复用,如果不清理自定义的 ThreadLocal变量,可能会影响后续业务逻辑和造成内存泄露等问题。尽量在代理中使用try-finally块进行回收。Examples/*** @author caikang* @date 2017/04/07*/public class UserHolder {private static final ThreadLocal<User> userThreadLocal = new ThreadLocal<User>();public static void set(User user){userThreadLocal.set(user);}public static User get(){return userThreadLocal.get();}public static void remove(){userThreadLocal.remove();}}/*** @author caikang* @date 2017/04/07*/public class UserInterceptor extends HandlerInterceptorAdapter {@Overridepublic boolean preHandle(HttpServletRequest request,HttpServletResponse response, Object handler) throws Exception {UserHolder.set(new User());return true;}@Overridepublic void afterCompletion(HttpServletRequest request,HttpServletResponse response, Object handler, Exception ex) throws Exception {UserHolder.remove();}}   

43.所有的类都必须添加创建者信息。

NameClassMustHaveAuthorRuleSeverityMajorMessage所有的类都必须添加创建者信息。Description说明:在设置模板时,注意IDEA的@author为${USER},而eclipse的@author为${user},大小写有区别,而日期的设置统一为yyyy/MM/dd的格式。Examples/*** Demo class* * @author keriezhang* @date 2016/10/31*/public class CodeNoteDemo {}   

44.定义DO/DTO/VO等POJO类时,不要加任何属性默认值。

NamePojoNoDefaultValueRuleSeverityMajorMessage定义DO/DTO/VO等POJO类时,不要加任何属性默认值。Examplespublic class DemoDO {String str;Integer a;}   

45.long或者Long初始赋值时,必须使用大写的L,不能是小写的l,小写容易跟数字1混淆,造成误解。

NameUpperEllRuleSeverityBlockerMessagelong或者Long初始赋值时,必须使用大写的L,不能是小写的l,小写容易跟数字1混淆,造成误解。ExamplesNegative example://It is hard to tell whether it is number 11 or Long 1.Long warn = 1l;
Positive example:Long notwarn = 1L;   

46.事务场景中,抛出异常被catch后,如果需要回滚,一定要手动回滚事务。

NameTransactionMustHaveRollbackRuleSeverityMajorMessage事务场景中,抛出异常被catch后,如果需要回滚,一定要手动回滚事务。ExamplesPositive example 1:/*** @author caikang* @date 2017/04/07*/@Service@Transactional(rollbackFor = Exception.class)public class UserServiceImpl implements UserService {@Overridepublic void save(User user) {//some code//db operation}}
Positive example 2:/*** @author caikang* @date 2017/04/07*/@Servicepublic class UserServiceImpl implements UserService {@Override@Transactional(rollbackFor = Exception.class)public void save(User user) {//some code//db operation}}
Positive example 3:/*** @author caikang* @date 2017/04/07*/@Servicepublic class UserServiceImpl implements UserService {@Autowiredprivate DataSourceTransactionManager transactionManager;@Override@Transactionalpublic void save(User user) {DefaultTransactionDefinition def = new DefaultTransactionDefinition();// explicitly setting the transaction name is something that can only be done programmaticallydef.setName("SomeTxName");def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);TransactionStatus status = transactionManager.getTransaction(def);try {// execute your business logic here//db operation} catch (Exception ex) {transactionManager.rollback(status);throw ex;}}}

47.异常类命名使用Exception结尾

NameExceptionClassShouldEndWithExceptionRuleSeverityCriticalMessage异常类命名使用Exception结尾Examplespublic class CacheDemoException extends Exception{}   

48.使用集合转数组的方法,必须使用集合的toArray(T[] array),传入的是类型完全一样的数组,大小就是list.size()

NameClassCastExceptionWithToArrayRuleSeverityCriticalMessage使用集合转数组的方法,必须使用集合的toArray(T[] array),传入的是类型完全一样的数组,大小就是list.size()ExamplesNegative example:  Integer[] a = (Integer [])c.toArray();
Positive example: Integer[] b = (Integer [])c.toArray(new Integer[c.size()]);   

49.除常用方法(如getXxx/isXxx)等外,不要在条件判断中执行复杂的语句,将复杂逻辑判断的结果赋值给一个有意义的布尔变量,以提高可读性。

NameAvoidComplexConditionRuleSeverityMajorMessage除常用方法(如getXxx/isXxx)等外,不要在条件判断中执行复杂的语句,将复杂逻辑判断的结果赋值给一个有意义的布尔变量,以提高可读性。Description说明:很多if语句内的逻辑相当复杂,阅读者需要分析条件表达式的最终结果,才能明确什么样的条件执行什么样的语句,那么,如果阅读者分析逻辑表达式错误呢?ExamplesNegative example:if ((file.open(fileName, "w") != null) && (...) || (...)) {// ...}
Positive example:boolean existed = (file.open(fileName, "w") != null) && (...) || (...);if (existed) {//...}   

50.Object的equals方法容易抛空指针异常,应使用常量或确定有值的对象来调用equals。

NameEqualsAvoidNullRuleSeverityCriticalMessageObject的equals方法容易抛空指针异常,应使用常量或确定有值的对象来调用equals。Examplespublic void f(String str){String inner = "hi";if (inner.equals(str)) {System.out.println("hello world");}}   

51.所有的覆写方法,必须加@Override注解。

NameMissingOverrideAnnotationRuleSeverityBlockerMessage所有的覆写方法,必须加@Override注解。Description反例:getObject()与get0bject()的问题。一个是字母的O,一个是数字的0,加@Override可以准确判断是否覆盖成功。另外,如果在抽象类中对方法签名进行修改,其实现类会马上编译报错。Examples/*** @author caikang* @date 2016/12/24*/public class MissingOverrideAnnotationRule extends AbstractEclipseRule {@Overridepublic Object visit(ASTCompilationUnit node, Object data) {return super.visit(node, data);}}   

52.抽象类命名使用Abstract或Base开头

NameAbstractClassShouldStartWithAbstractNamingRuleSeverityCriticalMessage抽象类命名使用Abstract或Base开头Examplesabstract class BaseControllerDemo{}abstract class AbstractActionDemo{}   

53.中括号是数组类型的一部分,数组定义如下:String[] args

NameArrayNamingShouldHaveBracketRuleSeverityMajorMessage中括号是数组类型的一部分,数组定义如下:String[] argsExamplesString[] a = new String[3];   

54.使用CountDownLatch进行异步转同步操作,每个线程退出前必须调用countDown方法,线程执行代码注意catch异常,确保countDown方法可以执行,避免主线程无法执行至await方法,直到超时才返回结果。

NameCountDownShouldInFinallyRuleSeverityMajorMessage使用CountDownLatch进行异步转同步操作,每个线程退出前必须调用countDown方法,线程执行代码注意catch异常,确保countDown方法可以执行,避免主线程无法执行至await方法,直到超时才返回结果。Description说明:注意,子线程抛出异常堆栈,不能在主线程try-catch到。Examples/*** @author caikang* @date 2017/04/07*/public class CountDownExample {public void operate(CountDownLatch countDownLatch){try{System.out.println("business logic");}catch (RuntimeException e){// do something}finally {countDownLatch.countDown();}}}   

55. 方法名、参数名、成员变量、局部变量都统一使用lowerCamelCase,必须遵从驼峰形式

NameLowerCamelCaseVariableNamingRuleSeverityCriticalMessage方法名、参数名、成员变量、局部变量都统一使用lowerCamelCase,必须遵从驼峰形式

56. 不能在finally块中使用return,finally块中的return返回后方法结束执行,不会再执行try块中的return语句。

NameAvoidReturnInFinallyRuleSeverityCriticalMessage不能在finally块中使用return,finally块中的return返回后方法结束执行,不会再执行try块中的return语句。ExamplesNegative example:public static Long readFileLength(String fileName) {try {File file = new File(fileName);RandomAccessFile randomAccessFile = new RandomAccessFile(file, "r");return randomAccessFile.length();} catch (Exception e) {logger.error(e.getMessage(), e);} finally {countDownLatch.countDown();return 0L;}}   

57.所有的包装类对象之间值的比较,全部使用equals方法比较。

NameWrapperTypeEqualityRuleSeverityBlockerMessage所有的包装类对象之间值的比较,全部使用equals方法比较。Description说明:对于Integer var=?在-128至127之间的赋值,Integer对象是在IntegerCache.cache产生,会复用已有对象,这个区间内的Integer值可以直接使用==进行判断,但是这个区间之外的所有数据,都会在堆上产生,并不会复用已有对象,这是一个大坑,推荐使用equals方法进行判断。ExamplesInteger a = 235;Integer b = 235;if (a.equals(b)) {// code}   

58. 所有的枚举类型字段必须要有注释,说明每个数据项的用途。

NameEnumConstantsMustHaveCommentRuleSeverityCriticalMessage所有的枚举类型字段必须要有注释,说明每个数据项的用途。Examplespublic enum TestEnum {/*** agree*/agree("agree"),/*** reject*/reject("reject");private String action;TestEnum(String action) {this.action = action;}public String getAction() {return action;}}

阿里巴巴Java代码规范相关推荐

  1. 解读阿里巴巴 Java 代码规范(2): 从代码处理等方面解读阿里巴巴 Java 代码规范...

    前言 2017 年阿里云栖大会,阿里发布了针对 Java 程序员的<阿里巴巴 Java 开发手册(终极版)>,这篇文档作为阿里数千位 Java 程序员的经验积累呈现给公众,并随之发布了适用 ...

  2. 阿里巴巴Java“代码反潜机”P3C喜提首届中国优秀开源项目二等奖!

    12 月 12-14 日,由中国开源云联盟.中国电子技术标准化研究院和全国信标委云计算标准工作组主办的第八届中国云计算标准和应用大会在京举行. 聚焦企业上云和开源,大会公布了首届中国优秀开源项目的名单 ...

  3. 推荐几本提高Java代码规范、可读性、健壮性和可维护性的基本经典图

    一.背景 很多人不重视编码规范,不在意编程风格,不考虑代码的健壮性可维护性等. 很多人总有一种心态,就是我不读这些一样写代码,是的没错,是可以写! 但是更容易出各种bug,不知不觉会挖很多坑,团队合作 ...

  4. IDEA工具(阿里巴巴)代码规范检查插件

    1.代码规范 因为软件是需要人来维护的.这个人在未来很可能不是你.所以首先是为人编写程序,其次才是计算机 不要过分追求技巧,降低程序可读性. 简洁的代码可以让BUG无处藏身.要写出明显没有BUG的代码 ...

  5. 阿里巴巴Java开发规范线程池_阿里巴巴java编程规范.pdf

    阿里巴巴java编程规范 目录 一.编程规约1 (一) 命名规约1 (二) 常量定义3 (三) 格式规约4 (四) OOP 规约6 (五) 集合处理 10 (六) 并发处理 12 (七) 控制语句 1 ...

  6. 阿里巴巴 Java 编码规范最佳实践

    概述 最近在实际项目中使用 p3c for eclipse 插件进行检测,发现项目中有不少不符合 "阿里巴巴 Java 编码规范" 的代码,现在已经由之前的 2000+ 个优化到 ...

  7. MyEclipse中阿里JAVA代码规范插件(P3C)的安装及使用

    JAVA代码规范插件(P3C)是阿里巴巴2017年10月14日在杭州云栖大会上首发的,使之前的阿里巴巴JAVA开发手册正式以插件形式公开走向业界.插件的相关信息及安装包都可以在GitHub(https ...

  8. 阿里巴巴java开发规范学习

    目录 一.编程规约 1.1 命名风格 1.2 常量定义 1.3 代码格式 ​1.4 OOP规约 1.5 集合处理 二.异常 三.MYSQL数据库 3.1 建表规约 3.2 索引规约 3.3 SQL语句 ...

  9. Java代码规范、格式化和checkstyle检查配置文档

    为便于规范各位开发人员代码.提高代码质量,研发中心需要启动代码评审机制.为了加快代码评审的速度,减少不必要的时间,可以加入一些代码评审的静态检查工具,另外需要为研发中心配置统一的编码模板和代码格式化模 ...

最新文章

  1. 一步步优化JVM五:优化延迟或者响应时间(1)
  2. java web如何配置ask_Javaweb新手之路之JavaWeb开发环境配置篇
  3. 工程中DSP代码片断
  4. MyEclipse 9.0的激活机制
  5. sql server中数据约束相关的查询
  6. SAP系统的模块分类
  7. Matlab中的各种运算符的用法
  8. 上海地图全图可放大_上海地图下载-上海地图全图高清版大图-地之图下载
  9. win7系统怎样搭建电影服务器,win7系统免费看电影的操作方法
  10. SpringBoot之九重九阳神功
  11. C语言输出平行四边形,菱形
  12. 前端-table表格隔行变色
  13. 英雄联盟手游服务器维护中,英雄联盟手游Server is currently under maintenance解决方法...
  14. 计算器 控制器 计算机的神经中枢,计算机基础知识(9).ppt
  15. python常用数据作图--matplotlib用法(相关设置及常用图)
  16. DO、DTO、BO、AO、VO、POJO
  17. IAP-应用内购买(部分)
  18. 网络订餐平台实现与测试
  19. 云签约,云培训,云办公,云指挥... 欧冶工业品,用数字化赋能企业高效协作
  20. 如何查看操作系统的块大小

热门文章

  1. Unity中的几种渲染队列
  2. 手把手之:教你怎样制作iPhone电子书
  3. 嵌入式-STM32-定时器原理与操作
  4. 什么蓝牙耳机性价比高?总结5款高性价比平价蓝牙耳机
  5. 网络日志管理_企业网络日志对具体对网络安全维护有哪些帮助?
  6. 测试小白应该了解的软件测试术语!
  7. 项目分享:模拟博客园登录
  8. linux netstat Netstat是在内核中访问网络连接状态及其相关信息的程序,它能提供TCP连接,TCP和UDP监听,进程内存管理的相关报告。
  9. 编译原理学习笔记:字母表上的运算(乘积、n次幂、正闭包、克林闭包)、串上的运算(连接、幂)
  10. 【转】关于TransactionScope出错:“与基础事务管理器的通信失败”的解决方法