摘要:帮助公司部署了一套sonar平台,经过一段时间运行,发现有一些问题出现频率很高,因此有必要将这些问题进行整理总结和分析,避免再次出现类似问题。

作者原创技术文章,转载请注明出处

===================================================================

id: 85 name:Broken Null Check  type:CODE SMELL  severity:CRITICAL

Comment:The null check is broken since it will throw a Nullpointer itself. The reason is that a method is called on the object when it is null. It is likely that you used || instead of && or vice versa. <p> This rule is deprecated, use {rule:squid:S1697} instead. </p>  definition:null检查是坏的,因为它将抛出一个Nullpointer本身。 原因是当对象为空时调用该方法。 很可能你使用|| 而不是&&,反之亦然。

advice: 不合规案例: if (str == null && str.length() == 0) { System.out.println("String is empty"); } if (str != null || str.length() > 0) { System.out.println("String is not empty"); } 合规案例: if (str == null || str.length() == 0) { System.out.println("String is empty"); } if (str != null && str.length() > 0) { System.out.println("String is not empty"); }

-------------------------------------------------------------------

id:123  name:Useless Operation On Immutable  type:CODE SMELL  severity:CRITICAL

Comment:An operation on an Immutable object (BigDecimal or BigInteger) won't change the object itself. The result of the operation is a new object. Therefore, ignoring the operation result is an error.

definition:示例代码: import java.math.*; class Test { void method1() { BigDecimal bd=new BigDecimal(10); bd.add(new BigDecimal(5)); // 这里违背了规则 } void method2() { BigDecimal bd=new BigDecimal(10); bd = bd.add(new BigDecimal(5)); // 这里没有违背规则 } }

advice: 对不可变对象(BigDecimal或BigInteger)的操作不会更改对象本身。 操作的结果是一个新的对象。 因此忽略操作结果是一个错误。

-------------------------------------------------------------------

id: 169 name:Empty Finally Block  type:CODE SMELL  severity:CRITICAL

Comment:<p> Avoid empty finally blocks - these can be deleted. </p> <p> This rule is deprecated, use {rule:squid:S00108} instead. </p>

definition:这些是可以删掉的。不合规案例: for (int i = 0; i < 42; i++){} // Empty on purpose or missing piece of code ?

advice: 空的 finally 块:避免空的 finally 块

-------------------------------------------------------------------

id:  263 name:  type:  severity:  Comment: 

definition:使用equals()比较对象引用; 避免用==,或者 != 进行比较。

advice:

不合规案例:
String str1 = "blue";
String str2 = "blue";
String str3 = str1;

if (str1 == str2)
{
System.out.println("they're both 'blue'"); // this doesn't print because the objects are different
}

if (str1 == "blue")
{
System.out.println("they're both 'blue'"); // this doesn't print because the objects are different
}

if (str1 == str3)
{
System.out.println("they're the same object"); // this prints
}
合规案例:
String str1 = "blue";
String str2 = "blue";
String str3 = str1;

if (str1.equals(str2))
{
System.out.println("they're both 'blue'"); // this prints
}

if (str1.equals("blue"))
{
System.out.println("they're both 'blue'"); // this prints
}

if (str1 == str3)
{
System.out.println("they're the same object"); // this still prints, but it's probably not what you meant to do
}

-------------------------------------------------------------------

id: 264 name:  type:  severity:  Comment: 

definition:空的 Synchronized 块:避免空的 synchronized 块 - 它们是无用的

advice: 不合规案例:

for (int i = 0; i < 42; i++){} // Empty on purpose or missing piece of code ?

-------------------------------------------------------------------

id:272  name:  type:  severity:  Comment: 

definition:  没有经验的程序员有时会混淆比较概念,并使用equals()来比较null值

advice:

不合规案例:
interface KitchenTool { ... };
interface Plant {...}

public class Spatula implements KitchenTool { ... }
public class Tree implements Plant { ...}
//...
Spatula spatula = new Spatula();
KitchenTool tool = spatula;
KitchenTool [] tools = {tool};

Tree tree = new Tree();
Plant plant = tree;
Tree [] trees = {tree};

if (spatula.equals(tree)) { // Noncompliant; unrelated classes
// ...
}
else if (spatula.equals(plant)) { // Noncompliant; unrelated class and interface
// ...
}
else if (tool.equals(plant)) { // Noncompliant; unrelated interfaces
// ...
}
else if (tool.equals(tools)) { // Noncompliant; array & non-array
// ...
}
else if (trees.equals(tools)) { // Noncompliant; incompatible arrays
// ...
}
else if (tree.equals(null)) { // Noncompliant
// ...
}

-------------------------------------------------------------------

id: 796 name:  type:  severity:  Comment: 

definition:此方法调用notify()而不是notifyAll()

advice: Java监视器通常用于多个条件。 调用notify()只唤醒一个线程,这意味着线程唤醒可能不是等待调用者满足的条件的线程。

-------------------------------------------------------------------

id:800  name:  type:  severity:  Comment: 

definition:此构造函数读取尚未分配值的字段。 这通常是由程序员错误地使用该字段而不是构造函数的参数之一引起的。

advice:

此构造方法中使用了一个尚未赋值的字段或属性。
String a;
public SA() {
String abc = a;
System.out.println(abc);
}

-------------------------------------------------------------------

id: 802 name:  type:  severity:  Comment: 

definition: 格式字符串定义错误

advice: 例如:formatter.format("%<s %s", "a", "b"); 抛出MissingFormatArgumentException异常

-------------------------------------------------------------------

id:806  name:  type:  severity:  Comment: 

definition:此代码创建一个异常(或错误)的对象,但不会用它做任何事情

advice:

例如:if (x < 0)
new IllegalArgumentException("x must be nonnegative");
这可能是程序员的意图抛出创建的异常:
if (x < 0)
throw new IllegalArgumentException("x must be nonnegative");

-------------------------------------------------------------------

id:811  name:  type:  severity:  Comment: 

definition:有一个语句或分支,如果执行保证在此时值为空,并且该值保证被取消引用(除了涉及运行时异常的转发路径之外)。

advice: 在正常的null判断分支上,对象去除引用操作是受保护的不允许的

-------------------------------------------------------------------

id: 815 name:  type:  severity:  Comment: 

definition:"equals(Object o)"方法不能对参数o的类型做任何的假设。比较此对象与指定的对象。当且仅当该参数不为 null,并且是表示与此对象相同的类型的对象时,结果才为 true

advice:

示例代码:
public class Foo {
// some code
public void equals(Object o) {
Foo other = (Foo) o;
// the real equals code
}
}
原因:
当你在实现类的equals方法时,不应该对参数有任何的预先设定。如上代码所写,
则设定了参数o肯定是Foo类的一个对象.但是如果在函数调用时,参数o不是一个Foo类或其子类,
就会导致代码会抛出一个ClassCastException。因此在实现equals方法,应该加一个判断,如果参数o不是一个Foo类对象,则返回false。

-------------------------------------------------------------------

id: 824 name:  type:  severity:  Comment: 

definition:该代码同步一个封装的原始常量,例如一个Boolean类型。

advice:

private static Boolean inited = Boolean.FALSE;
...
synchronized(inited) {
if (!inited) {
init();
inited = Boolean.TRUE;
}
}
...
由于通常只存在两个布尔对象,此代码可能是同步的其他无关的代码中相同的对象,这时会导致反应迟钝和可能死锁

-------------------------------------------------------------------

id: 827 name:  type:  severity:  Comment: 

definition:  可以为null的值存储在已注释为@Nonnull的字段中。

advice: 为一个已经声明为不能为null值的属性赋值为null

-------------------------------------------------------------------

id:831  name:  type:  severity:  Comment: 

definition: 调用具有可变数量参数的格式字符串方法,但传递的参数数与格式字符串中%占位符的数量不匹配。 这可能不是作者的意图。

advice: 错误用法 - 格式化字符串参数的数目与占位符不相等

-------------------------------------------------------------------

id: 844 name:  type:  severity:  Comment: 

definition:

某些异常控制路径上的引用值为空,在此处将被解引用。 当执行代码时,这可能会导致NullPointerException异常。 请注意,因为FindBugs目前不修剪不可行的异常路径,这可能是一个错误的警告。
另请注意,FindBugs将switch语句的默认情况视为异常路径,因为默认情况通常是不可行的。

advice: 在异常null值处理分支调用的方法上,可能存在对象去除引用操作

-------------------------------------------------------------------

id:846  name:  type:  severity:  Comment: 

definition: 没有足够的参数传递以满足格式字符串中的占位符。 执行此语句时将发生运行时异常。

advice: String的format操作缺少必要的参数。

-------------------------------------------------------------------

id: 849 name:  type:  severity:  Comment: 

definition:该代码将保证为非负的值与负常数或零进行比较。

advice: 保证非负数和负数进行比较

-------------------------------------------------------------------

id: 855 name:  type:  severity:  Comment: 

definition:  hasNext()方法调用next()方法。

advice:  这几乎肯定是错误的,因为hasNext()方法不应该改变迭代器的状态,而下一个方法应该改变迭代器的状态。

-------------------------------------------------------------------

id:856  name:  type:  severity:  Comment: 

definition: 该方法似乎在循环中使用连接构建一个String。 在每次迭代中,String将转换为StringBuffer / StringBuilder,附加到并转换为String。 这可以导致迭代次数中的二次成本,因为每个迭代中重新生成增长的字符串。

advice:

通过使用StringBuffer(或Java 1.5中的StringBuilder)可以获得更好的性能。
例如:
// 不好的写法
String s = "";
for (int i = 0; i < field.length; ++i) {
s = s + field[i];
}

//优化的写法
StringBuffer buf = new StringBuffer();
for (int i = 0; i < field.length; ++i) {
buf.append(field[i]);
}
String s = buf.toString();

-------------------------------------------------------------------

id:857  name:  type:  severity:  Comment: 

definition:

格式字符串占位符与相应的参数不兼容。 例如System.out.println(“%d \ n”,“hello”);
%d占位符需要一个数字参数,但是却传递一个字符串值。 执行此语句时将发生运行时异常。

advice:

错误使用参数类型来格式化字符串

-------------------------------------------------------------------

id:873  name:  type:  severity:  Comment: 

definition:

代码在interned String上同步。

private static String LOCK =“LOCK”;
...
   synchronized(LOCK){...}
...

advice:

常量字符串被实体化并由JVM加载的所有其他类共享。 因此,这可能锁定什么对象导致其他代码也可能被锁。 这可能导致阻塞和死锁行为。

-------------------------------------------------------------------

id: 878 name:  type:  severity:  Comment:  definition: 按位添加有符号字节值。添加一个字节值和已知具有8个较低位清除的值。 在对值进行任何按位操作之前,从字节数组加载的值将被扩展为32位。 因此,如果b [0]包含值0xff,并且x最初为0,则代码((x << 8)+ b [0])将对扩展0xff进行符号扩展,以获得0xffffffff,从而给出值0xffffffff作为 结果。

advice:

将字节数组打包到int中的以下代码是非常错误的:

int result = 0;
for(int i = 0; i < 4; i++)
result = ((result << 8) + b[i]);
需要改成如下:

int result = 0;
for(int i = 0; i < 4; i++)
result = ((result << 8) + (b[i] & 0xff));

-------------------------------------------------------------------

id:879  name:  type:  severity:  Comment: 

definition: 方法调用将null传递给非空参数。可能为null的值传递给非空方法参数。

advice:  参数注释为始终为非空值的参数,或者分析表明它始终被取消引用。

-------------------------------------------------------------------

id: 880 name:  type:  severity:  Comment: 

definition:此构造函数读取尚未分配值的字段。 这通常是由程序员错误地使用该字段而不是构造函数的参数之一引起的。

advice:

此构造方法中使用了一个尚未赋值的字段或属性。例如:
String a;
public SA() {
String abc = a;
System.out.println(abc);
}

===================================================================

更多原创测试技术文章同步更新到微信公众号 :三国测,敬请扫码关注个人的微信号,感谢!

感谢阅读,作者原创技术文章,转载请注明出处

附录:参考文献&参考文章

Java代码规范小结(一):http://www.jianshu.com/p/b50f01eeba4d

FindBugs Report安全代码检查工具问题解析:http://blog.csdn.net/wwbmyos/article/details/50549650

FindBugs规则整理(转载):http://blog.csdn.net/hufang_lele/article/details/47090215

详解FindBugs的各项检测器:http://blog.csdn.net/yang1982_0907/article/details/18606171

其他推荐相关阅读:

单元测试系列之一:如何使用JUnit、JaCoCo和EclEmma提高单元测试覆盖率

测试系列之二:Mock工具Jmockit实战

单元测试系列之三:JUnit单元测试规范

单元测试系列之四:Sonar平台中项目主要指标以及代码坏味道详解

单元测试系列之五:Mock工具之Mockito实战

单元测试系列之六:JUnit5 技术前瞻

单元测试系列之七:Sonar 数据库表关系整理一(rule相关)

单元测试系列之八:Sonar 数据库表关系整理一(续)

单元测试系列之九:Sonar 常用代码规则整理(一)

单元测试系列之十:Sonar 常用代码规则整理(二)

单元测试系列之十一:Jmockit之mock特性详解

单元测试系列之十:Sonar 常用代码规则整理(二)的更多相关文章

  1. Sonar 常用代码规则整理(二)

    摘要:公司部署了一套sonar,经过一段时间运行,发现有一些问题出现频率很高,因此有必要将这些问题进行整理总结和分析,避免再次出现类似问题. 作者原创技术文章,转载请注明出处 ============ ...

  2. 单元测试系列之九:Sonar 常用代码规则整理(一)

    更多原创测试技术文章同步更新到微信公众号 :三国测,敬请扫码关注个人的微信号,感谢! 摘要:公司部署了一套sonar,经过一段时间运行,发现有一些问题出现频率很高,因此有必要将这些问题进行整理总结和分 ...

  3. Sonar 常用代码规则整理(一)

    更多原创测试技术文章同步更新到微信公众号 :三国测,敬请扫码关注个人的微信号,感谢! 摘要:公司部署了一套sonar,经过一段时间运行,发现有一些问题出现频率很高,因此有必要将这些问题进行整理总结和分 ...

  4. 单元测试系列之八:Sonar 数据库表关系整理一(续)

    更多原创测试技术文章同步更新到微信公众号 :三国测,敬请扫码关注个人的微信号,感谢! 简介:Sonar平台是目前较为流行的静态代码扫描平台,为了便于使用以及自己二次开发,有必要对它的数据库结构进行学习 ...

  5. 单元测试系列之七:Sonar 数据库表关系整理一(rule相关)

    更多原创测试技术文章同步更新到微信公众号 :三国测,敬请扫码关注个人的微信号,感谢! 原文链接:http://www.cnblogs.com/zishi/p/7510072.html 简介:Sonar ...

  6. 单元测试系列之四:Sonar平台中项目主要指标以及代码坏味道详解

    更多原创测试技术文章同步更新到微信公众号 :三国测,敬请扫码关注个人的微信号,感谢! 原文链接:http://www.cnblogs.com/zishi/p/6766994.html 众所周知Sona ...

  7. C++语言笔记系列之十六——赋值兼容规则&amp;多继承的二义性

    1.赋值兼容规则 (1)派生类对象能够给基类对象赋值,这样的情况下派生类对象将从基类继承的成员的值赋值给一个基类对象:可是不同意将一个基类的对象赋值给一个派生类. (2)能够将派生类对象的地址赋给基类 ...

  8. MongoDB-JAVA-Driver 3.2版本常用代码全整理(3) - 聚合

    MongoDB的3.x版本Java驱动相对2.x做了全新的设计,类库和使用方法上有很大区别.例如用Document替换BasicDBObject.通过Builders类构建Bson替代直接输入$命令等 ...

  9. MongoDB-JAVA-Driver 3.2版本常用代码全整理(2) - 查询

    MongoDB的3.x版本Java驱动相对2.x做了全新的设计,类库和使用方法上有很大区别.例如用Document替换BasicDBObject.通过Builders类构建Bson替代直接输入$命令等 ...

随机推荐

  1. 获取UILabel的numberOfLine

    获取UILabel的numberOfLine CGFloat textH = [self.label.text boundingRectWithSize:CGSizeMake(width, MAXFL ...

  2. Hydra(爆破神器)

    PS:这款暴力密码破解工具相当强大,支持几乎所有协议的在线密码破解,其密码能否被破解关键在于字典是否足够强大.对于社会工程型渗透来说,有时能够得到事半功倍的效果.本文仅从安全角度去探讨测试,使用本文内 ...

  3. package,继承,访问修饰符

    1.package 包(package),用于管理程序中的类,可用于处理类的同名问题. 1.1定义package的方法 package 包名; package用于定义包,必须写在源文件有效代码的第一句 ...

  4. python的高级数组之稀疏矩阵

    稀疏矩阵的定义: 具有少量非零项的矩阵(在矩阵中,若数值0的元素数目远多于非0元素的数目,并且非0元素分布没有规律时,)则称该矩阵为稀疏矩阵:相反,为稠密矩阵.非零元素的总数比上矩阵所有元素的总数为矩 ...

  5. Apache2 httpd.conf配置文件中文版详解

    Apache2 httpd.conf配置文件中文版详解## 基于 NCSA 服务的配置文件.##这是Apache服务器主要配置文件.#它包含服务器的影响服务器运行的配置指令.#参见以取得关于这些指令的 ...

  6. PHP----------PHP自身的性能优化注意事项

    1.如果能将类的方法定义成static,就尽量定义成static,它的速度会提升将近4倍. 2.$row[’id’] 的速度是$row[id]的7倍. 3.echo 比 print 快,并且使用ech ...

  7. cycle标签和random两种方式美化表格

    一:cycle标签实现给表格变色 1. <style>标签里写好需要的颜色 2. 在要变色的地方(行/列)加固定的语句,按照顺序依次执行 代码: <!DOCTYPE html> ...

  8. Jmeter笔记(Ⅱ)使用Jmeter实现轻量级的接口自动化测试

    接口测试虽然作为版本的一环,但是也是有一套完整的体系,有接口的功能测试.性能测试.安全测试:同时,由于接口的特性,接口的自动化低成本高收益的,使用一些开源工具或一些轻量级的方法,在测试用例开发的成本不 ...

  9. NetCore持续踩坑

    坑1: vs2017 安装 .netcore2.2.2后,新建项目编译报错:.NET SDK 不支持降.NET Core2.2 设置为目标. 我以为是.netcore的sdk版本有误,于是我查看.ne ...

  10. Web应用启动时,后台自动启动一个线程(转)

    原文:http://blog.sina.com.cn/s/blog_6810dfc20101ipzq.html Web应用启动时,后台自动启动一个线程 (1)前言 前几天,manager问道一个问题: ...