阿里开发规范总结

时间:2024-04-13 21:55:36

安装步骤见 https://www.cnblogs.com/bestzhang/p/util.html

解释下Blocker/Critical/Major三个等级,

在 Snoar 中对代码规则有五个级别,这是前三个:崩溃/严重/重要 ,也就是说前两级别是必须要处理掉的。

阿里开发规范总结

 Blocker:

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

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

在使用正则表达式时,利用好其预编译功能,可以有效加快正则匹配速度。 说明:不要在方法体内定义:Pattern pattern = Pattern.compile(规则);

    public class XxxClass {
        // Use precompile
        private 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;
        }


    }

所有的覆写方法,必须加@Override注解。 反例:getObject()与get0bject()的问题。一个是字母的O,一个是数字的0,加@Override可以准确判断是否覆盖成功。另外,如果在抽象类中对方法签名进行修改,其实现类会马上编译报错。

获取当前毫秒数:System.currentTimeMillis(); 而不是new Date().getTime(); 说明:如果想获取更加精确的纳秒级时间值,用System.nanoTime。在JDK8中,针对统计时间等场景,推荐使用Instant类。
    public 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);
        }
    }

Critical

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

对于Service和DAO类,基于SOA的理念,暴露出来的服务一定是接口,内部的实现类用Impl的后缀与接口区别
            
    public interface DemoService{
        void f();
    }

    public class DemoServiceImpl implements DemoService {
        @Override
        public void f(){
            System.out.println("hello world");
        }
    }

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

    /**
    * max stock count
    */
    public static final Long MAX_STOCK_COUNT = 50000L;
       

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

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

Major

不允许任何魔法值(即未经定义的常量)直接出现在代码中。
        
Negative 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)) {
            //...
    }

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

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

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

及时清理不再使用的代码段或配置信息。 说明:对于垃圾代码或过时配置,坚决清理干净,避免程序过度臃肿,代码冗余。

循环体内,字符串的联接方式,使用StringBuilder的append方法进行扩展。 说明:反编译出的字节码文件显示每次循环都会new出一个StringBuilder对象,然后进行append操作,最后通过toString方法返回String对象,造成内存资源浪费。
            
Negative 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();

所有的抽象方法(包括接口中的方法)必须要用javadoc注释、除了返回值、参数、异常说明外,还必须指出该方法做什么事情,实现什么功能。 说明:如有实现和调用注意事项,请一并说明。
    /**
     * 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);

       

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

方法内部单行注释,在被注释语句上方另起一行,使用//注释。方法内部多行注释使用/* */注释。注意与代码对齐。
    public 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;
    }

 

类、类属性、类方法的注释必须使用javadoc规范,使用/**内容*/格式,不得使用//xxx方式和/*xxx*/方式。 说明:在IDE编辑窗口中,javadoc方式会提示相关注释,生成javadoc可以正确输出相应注释;在IDE中,工程调用方法时,不进入方法即可悬浮提示方法、参数、返回值的意义,提高阅读效率。
    /**
     *
     * 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;
        }
    }

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

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

避免采用取反逻辑运算符。 说明: 取反逻辑不利于快速理解,并且取反逻辑写法必然存在对应的正向逻辑写法。
            
Negative 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)) {
        // ...
    }

 

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

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