Ali-Check 【Blocker】

Blocker

Blocker直译过来是“雏形锻模”的意思,大意应该是要给开发者提供一个开发的模板。它在Ali-Check中的提示等级是最高的,在Android Studio中也是红色的标记
Blocker Inspections包含代码规范(消除歧义,增强可读性),性能调优等检测,值得开发者去了解,并且处理该类型的Inspections。

如何查看Blocker

在安装了Ali-Check的插件以后,如果想查看Blocker中所有的检测内容,可以点击Android Studio 的“File→Settings”,然后如下图所示,筛选Ali-Check中的Blocker即可。

Blocker目录

Blocker Inspections

从上面目录可以了解到,目前总共有11条Blocker提示信息,下面会对每条Blocker进行简单的记录。


1. long或者Long初始赋值时,必须使用大写的L

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;
    
  • 笔记
    这个Blocker很好理解,主要是为了提高代码的可读性,防止误导开发者。为了方便的看出long类型,有些时候小写的“l”还是有可能被误解成“1”的。

2.不要在foreach循环里进行元素的remove/add操作

不要在foreach循环里进行元素的remove/add操作,remove元素请使用Iterator方式。如果并发操作,需要对 Iterator 对象加锁。

  • Negative example
    List<String> originList = new ArrayList<String>();
    originList.add("22");
    for (String item : originList) { 
       //warn
       originList.add("bb");
    }  
    
  • Positive example
    Iterator<Integer> it=b.iterator();		 
    while(it.hasNext()){                      
       Integer temp =  it.next();             
       if (delCondition) {
           it.remove();
       }
    }
    
  • 笔记
    在foreach循环里面进行元素的remove/add操作,可能会导致程序异常崩溃。之前项目中有出现过异常。
    这篇文章有记录,不过根据文章步骤暂未复现。 不要在 foreach 循环里进行元素的 remove/add 操作

3. 在if/else/for/while/do语句中必须使用大括号

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

  • Negative example
    if (flag) System.out.println("hello world");
    
  • Positive example
    if (flag) {
            System.out.println("hello world");
    }
    
  • 笔记
    主要是为了提高代码的可读性。单行省略括号,这样看起来比较“高端”,但是降低代码可读性。特别是
    多行的时候有多个else,之后如果修改代码,会令人头大,也有很大的几率改错。

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

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

  • Negative example
     public class XxxClass {
            public Pattern getNumberPattern() {
                // Avoid use Pattern.compile in method body.
                Pattern localPattern = Pattern.compile("[0-9]+");
                return localPattern;
            }
     }
    
  • Positive example
     public class XxxClass {
            // Use precompile
            private static Pattern NUMBER_PATTERN = Pattern.compile("[0-9]+");
    }
    
  • 笔记
    性能优化类的Blocker,提高程序运行的效率。

5.多线程并行处理定时任务时,Timer运行多个TimeTask时,只要其中之一没有捕获抛出的异常,其它任务便会自动终止运行,使用ScheduledExecutorService则没有这个问题。
  • Ali
    //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方法比较。

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

  • Positive example

      Integer a = 235;
      Integer b = 235;
      if (a.equals(b)) {
          // code
      }
    
  • 笔记
    如果用“==”比较Integer类,在超过 [-128, 127]范围的时候就会失效,需要特别注意

  • 经典题

    Integer i1 = 1;
    Integer i2 = 1;
    Integer i3 = 128;
    Integer i4 = 128;
    Log.i("", ""+(i1 == i2));
    Log.i("", ""+(i1.equals(i2)));
    Log.i("", ""+(i3 == i4));     
    Log.i("", ""+(i3.equals(i4)));
    

    输出结果

    true,true,false,true
    

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

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

  • Negative example
    getObject()与get0bject()的问题。一个是字母的O,一个是数字的0,加@Override可以准确判断是否覆盖成功。另外,如果在抽象类中对方法签名进行修改,其实现类会马上编译报错。
  • 笔记
    这种继承的方法没有@Override情况在项目中,还是有遇到过,不知道是不是老代码迁移的问题,
    @Override表示的是一种继承的关系,表示对父类的重写,有助于开发者更好的理解代码的结构。

8.线程池不允许使用Executors去创建

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

  • Executors各个方法的弊端:

    • 1.newFixedThreadPool和newSingleThreadExecutor:
      主要问题是堆积的请求处理队列可能会耗费非常大的内存,甚至OOM。
    • 2.newCachedThreadPool和newScheduledThreadPool:
      主要问题是线程数最大数是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
    

9.获取当前毫秒数:System.currentTimeMillis()

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

  • Negative example
    long b = new Date().getTime();
    
  • Positive example
    long a = System.currentTimeMillis();
    

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.避免通过一个类的对象引用访问此类的静态变量或静态方法

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

  • Negative example
    实例化了一个对象,然后用这个对象引用调用了对象的静态方法
    class Demo{
      private static void getxxx(){
      ...
      }
    }
    //实例化对象调用了对象的静态方法
    Demo demo =new Demo()
    demo.getxxx();
    
  • Positive example
    class Demo{
      private static void getxxx(){
      ...
      }
    }
    Demo.getxxx();
    

后记
### 如何在IDEA中安装和使用阿里巴巴Ali-CodeAnalysis插件 #### 安装方法 可以通过两种方式来安装阿里巴巴的 `Ali-CodeAnalysis` 插件:通过官方仓库在线安装或者通过本地文件手动安装。 1. **通过官方仓库在线安装** 打开 IntelliJ IDEA 的菜单栏,依次选择 `File -> Settings -> Plugins -> Browse repositories`,输入关键词 “Alibaba” 进行搜索即可看到对应的插件[^1]。点击“Install”,等待安装完成后重启 IDE 即可生效。 2. **通过本地文件手动安装** 如果无法访问官方仓库,可以从 GitHub 下载插件的 `.jar` 文件(地址为 https://github.com/alibaba/p3c/releases)。下载完毕后,在 IDEA 中进入 `File -> Settings -> Plugins -> Install Plugin from Disk`,选择下载好的 `.jar` 文件完成安装[^4]。 #### 使用方法 安装完成后,IDEA 会自动加载该插件并提供相应的功能支持。为了启用代码检查规则,需进一步配置: 1. 前往 `File -> Settings -> Editor -> Inspections` 菜单。 2. 在右侧列表中找到分类项 `Ali-Check`,其中包含了基于《阿里巴巴 Java 开发手册》制定的多条规则[^2]。 3. 用户可以根据实际需求调整每一条规则的行为,比如设置警告颜色或忽略某些特定规则。 #### 功能特点 此插件的核心作用在于依据《阿里巴巴 Java 开发手册》的内容对项目中的源码执行静态分析,帮助开发者发现潜在问题并改进代码质量。具体特性如下: - 提供多达 55 条详细的代码审查准则,覆盖命名约定、异常处理等多个方面; - 支持中文与英文界面切换,便于国际化团队协作[^3]; - 自动化程度高,能够随着新版本迭代不断优化和完善已有规则集; 以下是部分典型规则示例及其意义解释: | 规则编号 | 名称 | 描述 | |----------|-------------------------|----------------------------------------------------------------------| | Rule 01 | 避免使用过时API | 推荐替换陈旧函数调用以提高程序性能及安全性 | | Rule 08 | 循环体内不得存在耗时操作 | 减少不必要的计算负担从而提升运行效率 | #### 示例代码展示 下面给出一段违反上述某几类规定的小例子以及修复后的对比形式: 原始写法存在问题的地方较多: ```java public class BadExample { public static void main(String[] args) throws Exception{ String str=null; System.out.println(str.length()); } } ``` 修正之后更加健壮可靠的新版本: ```java import org.apache.commons.lang3.StringUtils; public class GoodExample { public static final int MAX_RETRIES = 3; public static void main(String[] args){ String inputStr="hello world"; if (StringUtils.isNotBlank(inputStr)){ processString(inputStr); }else{ retryLogic(MAX_RETRIES,()->generateDefaultInput()); } } private static void processString(String validStr){ // 正常业务逻辑流程... } private static boolean generateDefaultInput(){ return false;//模拟生成默认值失败情况下的重试机制触发条件 } private static void retryLogic(int maxRetries,Runnable fallbackAction){ for(int i=0;i<maxRetries && !fallbackAction.run();i++){} } } ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值