美文网首页SonarQube
Alibaba Java Coding Guidelines 检

Alibaba Java Coding Guidelines 检

作者: 夹胡碰 | 来源:发表于2020-10-19 09:26 被阅读0次

1. 概述

Alibaba Java Coding Guidelines 的检测级别有三个,严重等级从高到低依次分别是 \color{red}{Blocker}\color{#FF9933}{Critical}\color{#CCCC99}{Major},下面介绍检测级别最低的\color{#CCCC99}{Major}级别的检测项目。

2. 全部检测项统计

3. 检测规则展示

- \color{#CCCC99}{Major}

1. iBATIS自带的queryForList(String statementName,int start,int size)不推荐使用
2. POJO类必须写toString方法。

使用工具类source> generate toString时,如果继承了另一个POJO类,注意在前面加一下super.toString。 说明:在方法执行抛出异常时,可以直接调用POJO的toString()方法打印其属性值,便于排查问题。

Positive example: 
    public class ToStringDemo extends Super{
        private String secondName;

        @Override
        public String toString() {
            return super.toString() + "ToStringDemo{" + "secondName='" + secondName + '\'' + '}';
        }
    }

    class Super {
        private String firstName;

        @Override
        public String toString() {
            return "Super{" + "firstName=" + firstName + '\'' + '}';
        }
    }
3. 不允许任何魔法值(即未经定义的常量)直接出现在代码中。
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)) {
            //...
    }
4. 中括号是数组类型的一部分,数组定义如下:String[] args
Positive example:
    String[] a = new String[3];
5. 事务场景中,抛出异常被catch后,如果需要回滚,一定要手动回滚事务。
Positive example 1:
    /**
     * @author caikang
     * @date 2017/04/07
     */
    @Service
    @Transactional(rollbackFor = Exception.class)
    public class UserServiceImpl implements UserService {
        @Override
        public void save(User user) {
            //some code
            //db operation
        }
    }
   
Positive example 2:
    /**
     * @author caikang
     * @date 2017/04/07
     */
    @Service
    public 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
     */
    @Service
    public class UserServiceImpl implements UserService {
        @Autowired
        private DataSourceTransactionManager transactionManager;

        @Override
        @Transactional
        public void save(User user) {
            DefaultTransactionDefinition def = new DefaultTransactionDefinition();
            // explicitly setting the transaction name is something that can only be done programmatically
            def.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;
            }
        }
    }
6. 使用CountDownLatch进行异步转同步操作,每个线程退出前必须调用countDown方法,线程执行代码注意catch异常,确保countDown方法可以执行,避免主线程无法执行至await方法,直到超时才返回结果。

说明:注意,子线程抛出异常堆栈,不能在主线程try-catch到。

Positive example:
    /**
     * @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();
            }
        }
    }
7. 关于基本数据类型与包装数据类型的使用标准如下:

1) 所有的POJO类属性必须使用包装数据类型。
2) RPC方法的返回值和参数必须使用包装数据类型。
3) 所有的局部变量推荐使用基本数据类型。 说明:POJO类属性没有初值是提醒使用者在需要使用时,必须自己显式地进行赋值,任何NPE问题,或者入库检查,都由使用者来保证。

Positive example:
    public class DemoDO {
        String str;
        Integer a;
    }
8. 包名统一使用小写,点分隔符之间有且仅有一个自然语义的英语单词。包名统一使用单数形式,但是类名如果有复数含义,类名可以使用复数形式
    com.alibaba.mpp.util / com.taobao.tddl.domain.dto
9. 单个方法的总行数不超过80行。

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

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

说明:对于垃圾代码或过时配置,坚决清理干净,避免程序过度臃肿,代码冗余。

Positive 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");
}
11. 后台输送给页面的变量必须加感叹号,${var}——中间加感叹号!。

说明:如果var=null或者不存在,那么${var}会直接显示在页面上。

    <input type="text" name="email" value="$!email"/>
    <input type="text" name="email" value="$!{email}"/>
12. 定义DO/DTO/VO等POJO类时,不要加任何属性默认值。
Positive example: 
    public class DemoDO {
        String str;
        Integer a;
    }
13. 循环体内,字符串的联接方式,使用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();
14. 所有的抽象方法(包括接口中的方法)必须要用javadoc注释、除了返回值、参数、异常说明外,还必须指出该方法做什么事情,实现什么功能。

说明:如有实现和调用注意事项,请一并说明。

Positive example:
    /**
     * 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);
15. 所有的类都必须添加创建者信息。

说明:在设置模板时,注意IDEA的@author为{USER},而eclipse的@author为{user},大小写有区别,而日期的设置统一为yyyy/MM/dd的格式。

Positive example:
    /**
     * Demo class
     * 
     * @author keriezhang
     * @date 2016/10/31
     */
    public class CodeNoteDemo {
    }
16. 方法内部单行注释,在被注释语句上方另起一行,使用//注释。方法内部多行注释使用/* */注释。注意与代码对齐。
Positive example:
    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;
    }
17. 注意 Math.random() 这个方法返回是double类型,注意取值的范围[0,1)(能够取到零值,注意除零异常),如果想获取整数类型的随机数,不要将x放大10的若干倍然后取整,直接使用Random对象的nextInt或者nextLong方法。
Negative example:
    Long randomLong =(long) (Math.random() * 10);

Positive example:
    Long randomLong = new Random().nextLong();
18. 测试类命名以它要测试的类的名称开始,以Test结尾
Positive example:      
    public class DemoTest {
    }
19. 禁止使用构造方法BigDecimal(double)的方式把double值转化为BigDecimal对象

说明:反编译出的字节码文件显示每次循环都会new出一个StringBuilder对象,然后进行append操作,最后通过toString方法返回String对象,造成内存资源浪费。

Negative example:
    BigDecimal good1 = new BigDecimal(0.1);
      
Positive example:
    BigDecimal good1 = new BigDecimal("0.1");
    BigDecimal good2 = BigDecimal.valueOf(0.1);
20. 类、类属性、类方法的注释必须使用javadoc规范,使用/内容/格式,不得使用//xxx方式和/xxx*/方式。 说明:在IDE编辑窗口中,javadoc方式会提示相关注释,生成javadoc可以正确输出相应注释;在IDE中,工程调用方法时,不进入方法即可悬浮提示方法、参数、返回值的意义,提高阅读效率。
Positive example:
    /**
     * 
     * 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;
        }
    }
21. 类名使用UpperCamelCase风格,必须遵从驼峰形式,但以下情形例外:(领域模型的相关命名)DO / BO / DTO / VO / DAO
22. 返回类型为基本数据类型,return包装数据类型的对象时,自动拆箱有可能产生NPE
Negative example:
    public int method() {
        Integer a = null;
        return a;
    }
23. 避免Random实例被多线程使用,虽然共享该实例是线程安全的,但会因竞争同一seed 导致的性能下降。

说明:Random实例包括java.util.Random 的实例或者 Math.random()的方式。

Positive example 1:
    /**
     * @author caikang
     * @date 2017/04/07
     */
    public class RandomInThread extends Thread {
        private Random random = new Random();

        @Override
        public 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();

        @Override
        public void run() {
            long t = random.nextLong();
        }
    }
24. 避免采用取反逻辑运算符。

说明: 取反逻辑不利于快速理解,并且取反逻辑写法必然存在对应的正向逻辑写法。

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

说明:很多if语句内的逻辑相当复杂,阅读者需要分析条件表达式的最终结果,才能明确什么样的条件执行什么样的语句,那么,如果阅读者分析逻辑表达式错误呢?

Negative example:
    if ((file.open(fileName, "w") != null) && (...) || (...)) {
        // ...
    }
     
Positive example:
    boolean existed = (file.open(fileName, "w") != null) && (...) || (...);
    if (existed) {
        //...
    }
26. 集合初始化时,指定集合初始值大小。

说明:HashMap使用如下构造方法进行初始化,如果暂时无法确定集合大小,那么指定默认值(16)即可。

 Negative example:   
   Map<String, String> map = new HashMap<String, String>();

 Positive example: 
   Map<String, String> map = new HashMap<String, String>(16);

相关文章

网友评论

    本文标题:Alibaba Java Coding Guidelines 检

    本文链接:https://www.haomeiwen.com/subject/iytfmktx.html