从Sonar上学习代码优化-代码异味案例

Sonar相信大家都不陌生了,很多公司都把Sonar当做代码质量检测的工具,通过Sonar来考察软件的质量,以及程序员的水平。我们在修改代码异味时,也逐渐提高了自己的编码水平。

图片

下面我们来看看在Sonar中常见的一些代码问题吧。

包装对象的比较

案例代码

//两边都为Integer类型
if(xxx.getLevel() == xxx.getCurrentLevel()) {
    ...
}

sonar检测问题

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

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

也就是说如果你使用的是包装类型的Integer,虽然在-128到127之间可以用==判断,但是超过这个值,就是两个对象之间的比较,用等号是不成立的。而我们是比较的内容,所以要用equals。

@Test
public void testInteger() {

    Integer a1 = 120;
    Integer a2 = 120;
    System.out.println("a1 == a2: " + (a1 == a2));

    Integer a3 = 200;
    Integer a4 = 200;
    System.out.println("a3 == a4: " + (a3 == a4));

    System.out.println("a3.equals(a4): " + (a3.equals(a4)));
}

运行结果:

a1 == a2: true
a3 == a4: false
a3.equals(a4): true

手动创建线程池,效果会更好

案例代码

private static ExecutorService executor = Executors.newSingleThreadExecutor();

Executors各个方法的弊端:

  • newFixedThreadPoolnewSingleThreadExecutor:主要问题是堆积的请求处理队列可能会耗费非常大的内存,甚至OOM。

  • newCachedThreadPoolnewScheduledThreadPool:主要问题是线程数最大数是Integer.MAX_VALUE,可能会创建数量非常多的线程,甚至OOM。

这里建议使用ThreadPoolExecutor的方式创建。

使用示例:

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();

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

案列代码

 Pattern pattern = Pattern.compile("^[1]\\d{10}$");

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

正确使用方式:

public class XxxClass {  
        private static Pattern NUMBER_PATTERN = Pattern.compile("^[1]\\d{10}$");
        public static Pattern getNumberPattern() {  
           return NUMBER_PATTERN;
        }
    }

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

案例代码

Map<String, Object> cache = new HashMap<>();

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

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

Arrays.asList()与Collections.singletonList()

Arrays.asList(strArray)返回值是仍然是一个可变的集合,但是返回值是其内部类,不具有add方法,可以通过set方法进行增加值,默认长度是10Collections.singletonList()返回的同样是不可变的集合,但是这个长度的集合只有1,可以减少内存空间。但是返回的值依然是Collections的内部实现类,同样没有add的方法,调用add,set方法会报错。

卫语句减少if-else嵌套

超过 3 层的 if-else 的逻辑判断代码可以使用卫语句、策略模式、状态模式等来实现。

示例:

    public void today() {
      if (isBusy()) {
       System.out.println(“change time.”);
       return; 
      }
      if (isFree()) {
       System.out.println(“go to travel.”);
       return;
      }
      return;
    }

SimpleDateFormat线程不安全不要定义为static变量

我们可以使用本地线程处理:

private static final ThreadLocal<DateFormat> df = new ThreadLocal<DateFormat>() {
     @ Override
     protected DateFormat initialValue() {
      return new SimpleDateFormat("yyyy-MM-dd");
     }
};

往期推荐

扫码二维码,获取更多精彩。或微信搜Lvshen_9,可后台回复获取资料

回复"java" 获取java电子书;

回复"python"获取python电子书;

回复"算法"获取算法电子书;

回复"大数据"获取大数据电子书;

回复"spring"获取SpringBoot的学习视频。

回复"面试"获取一线大厂面试资料

回复"进阶之路"获取Java进阶之路的思维导图

回复"手册"获取阿里巴巴Java开发手册(嵩山终极版)

回复"总结"获取Java后端面试经验总结PDF版

回复"Redis"获取Redis命令手册,和Redis专项面试习题(PDF)

回复"并发导图"获取Java并发编程思维导图(xmind终极版)

另:点击【我的福利】有更多惊喜哦。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值