【从findbug中学习代码规范】

本文探讨了Java编程中的PSC_PRESIZE_COLLECTIONS问题、类型转换优化、FindBugs警告修复、编码规范改进等,包括集合初始化、避免boxing/unboxing、内存优化和最佳API使用。阅读以提高代码质量和性能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、PSC_PRESIZE_COLLECTIONS

这个问题是由于集合的分配不合理导致,当我们知道集合的大小的时候,应该在构造集合时给一个初始值(有关默认初始值的知识参考阿里巴巴Java开发手册建议创建HashMap时设置初始化容量,但是多少合适呢? - HollisChuang - 博客园),推荐使用Guava里提供方法来初始指定大小的集合。

官方解释:这个方法使用默认构造函数分配集合,即使它预先知道集合中将放置多少项(或者至少可以合理地猜测),从而不必要地导致集合的中间重新分配。

您可以使用具有初始大小的构造函数,这样会好得多,但是由于映射和集合的加载因子,甚至这也不是一个正确的估计值。

如果您正在使用Guava,请使用它的方法来分配具有预先确定大小的映射和集合,以获得不重新分配的最佳机会,例如:

Sets.newHashSetWithExpectedSize (int)  构造HashSet

Maps.newHashMapWithExpectedSize (int) 构造HashMap

Lists.newArrayListWithExpectedSize(int) 构造ArryList

如果没有,一个很好的估计值应该是expectedSize / {LOADING_FACTOR}默认值为0.75

2、fb-contrib:NAB_NEEDLESS_BOXING_PARSE

这个问题是类型转换的问题 不推荐使用valueOf 因为将字符串解析为基本类型时是一个对象,如果需要的是基本类型编译器还会做un-boxing,影响性能

推荐使用:

int i = Integer.valueOf(s)改为int i= Integer.parseInt(s)

3、 findbugs:RCN_REDUNDANT_NULLCHECK_WOULD_HAVE_BEEN_A_NPE

官方解释:

某个值虽然在某处有被判断是否为null,但是这个值在该处并不可以为null,因为这个值被提前引用了,如果他有可能是null,在被引用的时候就会产生空指针异常,所以这里的判断也就是多余的,而在该判断之前的引用也可能是错误的

我的理解就是判断某个对象为空的行不对,判断为空之前已经用过这个对象了。错误的例子:

List<Long> evnOrRegionByProId = tagRelationDao.queryResourceId(map);

if (evnOrRegionByProId.size() > 0 && evnOrRegionByProId != null) {

        //
}

正确应该:

if (evnOrRegionByProId != null && evnOrRegionByProId.size() > 0) {}

错误例子2:

Object obj = RedisUtil.getMap(1, "Map_VC_NetTag_" + info.getResourceId(), fixInfos.get(0).getNetUuid());

NetWorkVo netWorkVo = JSON.parseObject(obj.toString(), NetWorkVo.class);

if (obj != null) {

}

obj对象已被使用 下面还判断是否为null

4 findbugs:MDM_STRING_BYTES_ENCODING

在创建string对象时和获取string对象的getBytes()时 建议给一个默认编码

错误的例子:

new String("aa");

“aaaa”.getBytes();

正确的例子:

new String("aa",StandardCharsets.UTF_8);

“aaaa”.getBytes(StandardCharsets.UTF_8);

5 findbugs:ISB_INEFFICIENT_STRING_BUFFERING

错误的使用stringbuffer

错误的例子:

string aa = wxp;

stringbuffer sb = new stringbuffer();

sb.append("我的名字"+aa);

正确的用法:

sb.append("我的名字");

sb.append(aa);

6、findbugs:squid:S2111

官方解释:

Because of floating point imprecision, you're unlikely to get the value you expect from the BigDecimal(double) constructor.

From the JavaDocs:

The results of this constructor can be somewhat unpredictable. One might assume that writing new BigDecimal(0.1) in Java creates a BigDecimal which is exactly equal to 0.1 (an unscaled value of 1, with a scale of 1), but it is actually equal to 0.1000000000000000055511151231257827021181583404541015625. This is because 0.1 cannot be represented exactly as a double (or, for that matter, as a binary fraction of any finite length). Thus, the value that is being passed in to the constructor is not exactly equal to 0.1, appearances notwithstanding.

Instead, you should use BigDecimal.valueOf, which uses a string under the covers to eliminate floating point rounding errors, or the constructor that takes a String argument.

错误例子:

double sum = datastore.getMaxFileSize()/1024/1024/1024;

BigDecimal freebig = new BigDecimal(free);

正确的例子:

double sum = datastore.getMaxFileSize()/1024/1024/1024;

BigDecimal freebig = BigDecimal.valueOf(free);

7、contrib:JPAI_TRANSACTION_ON_NON_PUBLIC_METHOD

官方解释是:不能在非公共的方法的加上spring @Transactional注解 因为会不生效。

8 、findbugs:BX_UNBOXING_IMMEDIATELY_REBOXED

三目运算符类型中间和两边要统一 

错误的例子:

max.put(IP, queryQuota.getIp() == null ? 0 : queryQuota.getIp());

正确的例子:

queryQuota.getIp() == null ? Integer.valueOf(0) : queryQuota.getIp()

9 、如果确认只含有单个字符请用char 而不是string

string a = "1";

最好用

char a = '1';

10、findbug WMI_WRONG_MAP_ITERATOR

Set<Object> keySet = properties.keySet();
Set<Entry<Object, Object>> keySet = properties.entrySet(); //性能更好更快 推荐使用这个取数据

KeySet(): 将Map中所有的键存入到set集合中。因为set具备迭代器。所有可以迭代方式取出所有的键,再根据get方法。获取每一个键对应的值。 keySet():迭代后只能通过get()取key

entrySet():

Set<Map.Entry<K,V>> entrySet() //返回此映射中包含的映射关系的 Set 视图。 Map.Entry表示映射关系。entrySet():迭代后可以e.getKey(),e.getValue()取key和value。返回的是Entry接口 。

11、fb-contrib:LSYC_LOCAL_SYNCHRONIZED_COLLECTION

在局部变量,无需定义成线程安全的方法内可以使用:

java.lang.StringBuilder

java.util.HashMap

java.util.ArrayList

替换掉:

StringBuffer、Hashtable、Vector  因为性能更好更快,有速度优势。

12、DM_STRING_CTOR

错误原因:new String("aaa");  推荐使用 String aa = "aaa"; 这样内存开销更小。

13、String[] starts = start.split("\\."); split里有特殊字符时建议转义,因为split里可以写正则表达式。

14、squid:S2095 

从jdk1.7开始官方建议用try-with-resource的方式来在处理关闭数据库连接、字符节流、字符流等

参考(Java语法糖 : try-with-resources - darrenqiao - 博客园

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值