美文网首页SonarQube
Alibaba Java Coding Guidelines 检

Alibaba Java Coding Guidelines 检

作者: 夹胡碰 | 来源:发表于2020-10-18 20:14 被阅读0次

    1. 概述

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

    2. 全部检测项统计

    3. 检测规则展示

    - \color{red}{Blocker}

    1. long或者Long初始赋值时,必须使用大写的L,不能是小写的l,小写容易跟数字1混淆,造成误解。
    Negative example:
        //It is hard to tell whether it is number 11 or Long 1.
        Long warn = 1l;
       
    Positive example:
        Long notwarn = 1L;
    
    2. 不要在foreach循环里进行元素的remove/add操作,remove元素请使用Iterator方式。
     Negative example:   
       List<String> originList = new ArrayList<String>();
       originList.add("22");
       for (String item : originList) { 
          //warn
          list.add("bb");
       }  
        
     Positive example: 
       Iterator<Integer> it=b.iterator();        
       while(it.hasNext()){                      
          Integer temp =  it.next();             
          if (delCondition) {
              it.remove();
          }
       }
    
    3. 在if/else/for/while/do语句中必须使用大括号,即使只有一行代码,避免使用下面的形式:if (condition) statements;
     Positive example: 
        if (flag) {
                System.out.println("hello world");
        }
    
    4. 在使用正则表达式时,利用好其预编译功能,可以有效加快正则匹配速度。

    说明:不要在方法体内定义:Pattern pattern = Pattern.compile(规则);

    Positive example: 
        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;
            }
        }
    
    5. 多线程并行处理定时任务时,Timer运行多个TimeTask时,只要其中之一没有捕获抛出的异常,其它任务便会自动终止运行,使用ScheduledExecutorService则没有这个问题。
    Positive example: 
        //org.apache.commons.lang3.concurrent.BasicThreadFactory
        ScheduledExecutorService executorService = new ScheduledThreadPoolExecutor(1,
            new BasicThreadFactory.Builder().namingPattern("example-schedule-pool-%d").daemon(true).build());
        executorService.scheduleAtFixedRate(new Runnable() {
            @Override
            public void run() {
                //do something
            }
        },initialDelay,period, TimeUnit.HOURS);
    
    6. 所有的包装类对象之间值的比较,全部使用equals方法比较。

    说明:对于Integer var=?在-128至127之间的赋值,Integer对象是在IntegerCache.cache产生,会复用已有对象,这个区间内的Integer值可以直接使用==进行判断,但是这个区间之外的所有数据,都会在堆上产生,并不会复用已有对象,这是一个大坑,推荐使用equals方法进行判断。

    Positive example: 
        Integer a = 235;
        Integer b = 235;
        if (a.equals(b)) {
            // code
        }
    
    7. 所有的覆写方法,必须加@Override注解。

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

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

    说明:Executors返回的线程池对象的弊端如下:
    1)FixedThreadPool和SingleThreadPool:
      允许的请求队列长度为Integer.MAX_VALUE,可能会堆积大量的请求,从而导致OOM。
    2)CachedThreadPool:
      允许的创建线程数量为Integer.MAX_VALUE,可能会创建大量的线程,从而导致OOM。

    Positive example 1:
        //org.apache.commons.lang3.concurrent.BasicThreadFactory
        ScheduledExecutorService 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 Pool
        ExecutorService 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 code
        userThreadPool.execute(thread);
    
    9. 获取当前毫秒数: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);
        }
    }
    
    10. 避免用Apache Beanutils进行属性的copy。

    说明:Apache BeanUtils性能较差,可以使用其他方案比如Spring BeanUtils, Cglib BeanCopier。

    TestObject a = new TestObject();
    TestObject b = new TestObject();
    a.setX(b.getX());
    a.setY(b.getY());
    
    11. 避免通过一个类的对象引用访问此类的静态变量或静态方法,无谓增加编译器解析成本,直接用类名来访问即可。

    相关文章

      网友评论

        本文标题:Alibaba Java Coding Guidelines 检

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