Sonar 问题修复Neither “Math.abs“ nor negation should be used on numbers that could be “MIN_VALUE“

本文详细介绍了如何解决SonarLint报告的Bugs,即使用`Math.abs(rand.nextInt())`可能导致负数的问题。通过分析Integer溢出和Math.abs()的潜在风险,提出了修改方案,即使用`rand.nextInt(Integer.MAX_VALUE)`来确保获取正数。同时,解释了整数操作的溢出行为,并提供了相关参考链接。
摘要由CSDN通过智能技术生成

本系列主要记录分享 SonarLint 扫描出来的Bugs问题修复方案

问题

Bugs描述:Use the original value instead.
在这里插入图片描述
问题代码:

Random rand = new Random();
// 这一行是被扫描出来有问题的代码
int randInt = Math.abs(rand.nextInt());

解决办法

Random rand = new Random();
int randInt = Math.abs(rand.nextInt(Integer.MAX_VALUE));

问题分析

SonarLint 扫描结果的大概意思:代码里 Math.abs() 取绝对值后的结果,仍可能是一个负数,所以建议:

  • 使用 Random.nextLong() 去获取目标结果值;
  • 直接去掉 Math.abs() 的使用,直接取 rand.nextInt() 的值。

是不是在想为什么 Math.abs() 取到的值仍可能是一个负数呢?

这里演示一种场景:

	@Test
    public void testDemo1() {
        Integer i = Math.abs(Integer.MIN_VALUE);
        System.out.println(i);
    }

结果展示:
在这里插入图片描述
我们都知道 Integer 的取值范围:-2147483648 ~ 2147483647,所以当我们对 Integer.MIN_VALUE 去绝对值(Math.abs())操作后,得到 2147483648 就超出了 int类型的取值范围。

Oracle docs: Integer Operations中有这么一段话:

The integer operators do not indicate overflow or underflow in any way.
整数的操作不会告诉我们向上溢出还是向下溢出。
——Oracle docs

所以,溢出的结果已由语言指定,独立于JVM版本:

  • Integer.MAX_VALUE + 1 == Integer.MIN_VALUE
  • Integer.MIN_VALUE - 1 == Integer. MAX_VALUE

其他整数类型也是如此。

所以 SonarLint 才会提示我们的代码最终目标是想获取一个正值的数,当前 Math.abs(rand.nextInt()) 写法获取的结果不一定是正数。

我之前写过一篇关于:Java 边界陷阱(边界值的校验) 的博客,大家有兴趣可以瞅瞅~

我这里的解决办法是,Random 取值时指定 n 的取值范围,这样取值就不会取出负数,

ps:Random.nextInt(int n),给定一个参数n,nextInt(n)将返回一个大于等于0小于n的随机数,即:0 <= nextInt(n) < n。

参考

Sonar检测Math.abs(new Random().nextInt()) “Use the original value instead”


感 谢 各 位 大 佬 的 阅 读,随 手 点 赞,日 薪 过 万~! !!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zhuzicc

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值