文档库 最新最全的文档下载
当前位置:文档库 › sonar错误

sonar错误


关于部分sonar报错的解决方法,以便后来新人查找,若有错误或不足,及时通知我,共同学习。

1.Write to static field from instance method:
描述: 通过实例方法更新静态属性
常见于常量类,直接通过类名.常量名获取的方式违背了封装的原则,findbugs不提倡使用,
而如果将常量改成静态成员变量,又因为spring不支持静态注入导致不能实现,
解决方法是非静态的setter调用静态的setter方法给静态成员变量赋值。
解决方法:
常量类F:
class F{
public static String a = “123”;
}
常量a改为静态成员变量,通过F.getA()获取,且由于spring不支持静态注入,改为:
class F{
private static String a;
public static Integer getA() {
return a;
}
public void setA(String a) {
setAValue(a);
}
public static void setAValue(String a) {
F.a = a;
}
}

2. equals() method does not check for null argument
描述:对于equals方法,要检查参数是否为空,这个错误是因为没有判断参数的类型是否一致
解决方法:加一个if判断语句:
if (!(ta instanceof Table)){
return false;
}

3.Equals method should not assume anything about the type of its argument
描述:equals方法应该判断参数类型
解决方法:和上一个错误一样 ,加一个if判断语句
if (!(ta instanceof Table)){
return false;
}

4.Static Variable Name
描述:静态变量命名不规范
解决方法:规范命名 '^[a-z][a-zA-Z0-9]*$'.

5.Nullcheck of value previously dereferenced
描述:这里检查一个值是否为空,但在此处它不能为空,因为如果为空的话,在此前就会抛出异常。
解决方法:(判空语句提前)在会抛出空指针错误的地方前判断是否为空。
例如:if (!limits.equals(noLimit)) {
if (limits != null && limits.size() > 0) {
if (!limits.contains(strID)){
continue;
}
}
}改为:
if (limits != null && limits.size() > 0) {
if (!limits.equals(noLimit)) {
if (!limits.contains(strID)){
continue;
}
}
}

6.Test for floating point equality
描述:比较两个浮点数是否相等,直接比较可能会因为误差的原因导致判断不准确(这是底层的原因)
解决方法:考虑误差比较
例如:datagrp.data[iData] != Double.MIN_VALUE
改为:Math.abs(datagrp.data[iData]-Double.MIN_VALUE)>0.0000001

7.Try-catch blocks should not be nested
描述:try catch 不应该被嵌套
解决方法:
try {
try { // Non-Compliant
doSomething();
} catch (RuntimeException e) {
/* Ignore */
}

doSomethingElse();
} catch (Exception e) {
/* ... */
}改为:
try {
dedicatedMethod(); // Compliant
doSomethingElse();
} catch (Exception e)

{
/* ... */
}

/* ... */

private void dedicatedMethod() {
try { // Compliant
doSomething();
} catch (RuntimeException e) {
/* Ignore */
}
}

8.Utility classes should not have a public constructor
描述:实用工具类不应该有一个默认的公共的构造函数.由于任何类都有默认的公共的无参构造函数
解决方法:在代码中加上一个私有的构造函数,如下:
private class YourClass(){ }
9. Malicious code vulnerability - May expose internal representation by incorporating reference to mutable object
问题描述:可能因使引用可指向多个对象而暴露内部存储结构。
这代码使一个指向外部多个对象的引用指向了一个内部对象存储地址。
如果实例被未被信任代码访问或多个对象发生了未经检查的改变就会危及安全性或其它重要属性,
你需要去做一些不同的事情。存储一个对象的拷贝在许多情况下会是一个更好的方法。
解决方法:
public void setOpDate(java.util.Date opDate)
{
this.opDate = opDate;
}
改为:
public void setOpDate(java.util.Date opDate)
{
java.util.Date date = opDate;
this.opDate = date;
}

10. Strings literals should be placed on the left side when checking for equality
问题描述:直接写的字符串应该放在equals的左边
解决方法:
System.out.println("Equal? " + myString.equals("foo")); 或
System.out.println("Equal? " + (myString != null && myString.equals("foo")));
改为:
System.out.println("Equal?" + "foo".equals(myString));

11. Local variables should not shadow class fields
问题描述:局部变量不应该和类属性重名
解决方法:局部变量重命名

12.Overriding methods should do more than simply call the same method in the super class
问题描述:重写的方法不应该只是简单的调用super的相同的方法
解决方法:去掉该方法 或加上@Id注释
public void doSomething() { // Non-Compliant
super.doSomething();
}

@Override
public boolean isLegal(Action action) { // Non-Compliant
return super.isLegal(action);
}

@Override
public boolean isLegal(Action action) { // Compliant - not simply forwarding the call
return super.isLegal(new Action(/* ... */));
}

@Id
@Override
public int getId() { // Compliant - there is annotation different from @Override
return super.getId();
}

13.Constructor Calls Overridable Method 中的Overridable method *** called during object construction
问题描述:构造方法中调用重写的方法 中 构造方法中调用可重写的方法
问题重现:
public class SeniorClass {
public SeniorClass(){
toString(); //may throw NullPointerException if overridden
}
public String toString(){
retur

n "IAmSeniorClass";
}
}
public class JuniorClass extends SeniorClass {
private String name;
public JuniorClass(){
super(); //Automatic call leads to NullPointerException
name = "JuniorClass";
}
public String toString(){
return name.toUpperCase();
}
}
解决方法:将可重写的方法改为不可重写,即加 final修饰

14. Use Arrays As List
The class java.util.Arrays has a asList method that should be use when you want to create a new List from an array of objects. It is faster than executing a loop to cpy all the elements of the array one by one
问题描述:jdk1.6版本及更高的版本,增加了一个直接将数组中所有的元素添加到list中的方法
用这个方法,比用循环一个一个添加更好.
解决方法:
List v = new ArrayList();
for(int i = 0;i < nColNum;i++)
{
v.add(strTitle[i]);
}
改为:
List v = new ArrayList();
v = Arrays.asList(strTitle);

15. Inefficient use of keySet iterator instead of entrySet iterator
问题描述:用keySet 方式遍历Map的性能不如entrySet性能好
解决方法:
Iterator keySetIterator = map.keySet().iterator();
while (keySetIterator.hasNext()) {
String key = keySetIterator.next();
String value = map.get(key);

} 改为:
Iterator> entryKeyIterator = map.entrySet().iterator();
while (entryKeyIterator.hasNext()) {
Entry e = entryKeyIterator.next();
String value=e.getValue();
}
原因分析:
通过查看源代码发现,调用这个方法keySetMap.keySet()会生成KeyIterator迭代器,其next方法只返回其key值.
private class KeyIterator extends HashIterator {
public K next() {
return nextEntry().getKey();
}
}
而调用entrySetMap.entrySet()方法会生成EntryIterator 迭代器,其next方法返回一个Entry对象的一个实例,其中包含key和value.
private class EntryIterator extends HashIterator> {
public Map.Entry next() {
return nextEntry();
}
}
二者在此时的性能应该是相同的,但方式一再取得key所对应的value时,此时还要访问Map的这个方法,这时,方式一多遍历了一次table.
public V get(Object key) {
Object k = maskNull(key);
int hash = hash(k);
int i = indexFor(hash, table.length);
Entry e = table[i];
while (true) {
if (e == null)
return null;
if (e.hash == hash && eq(k, e.key))
return e.value;
e = e.next;
}
}

16.Dead store to local variable
问题描述:本地变量存储了闲置不用的对象
原因分析:(以下面的代码为例)List v = new ArrayList();然后立即又将v对象指向

了Arrays.asList(strTitle);
为了避免不必要的空间浪费,可以直接将v指向Arrays.asList(strTitle)
解决方法:例如:
List v = new ArrayList();
v = Arrays.asList(strTitle);
改为:
List v = Arrays.asList(strTitle);

17. Possible null pointer dereference
问题描述:可能会出现空指针错误
解决方法:先判断是否为空,如果非空如何处理,如果为空如何处理

18. Security - Unencrypted socket [find-sec-bugs]
问题描述:这样创建socket不安全
解决方法:
https://www.wendangku.net/doc/7315194074.html,.Socket socket = new https://www.wendangku.net/doc/7315194074.html,.Socket(strServer,nPort);
改为:
https://www.wendangku.net/doc/7315194074.html,.Socket socket = SSLSocketFactory.getDefault().createSocket(strServer,nPort);

19.Class doesn't override equals in superclass
问题描述:子类没有重写父类的equals方法
解决方法:
在子类中加入:
public boolean equals(Object obj){
return super.equals(obj);
}
public int hashCode(){
return super.hashCode();
}

20.Boolean Instantiation --Avoid instantiating Boolean objects; you can reference Boolean.TRUE, Boolean.FALSE, or call Boolean.valueOf() instead.
问题描述:不要通过new Boolean来给一个Boolean赋值
解决方法:
Boolean AutoManaged = new Boolean(configure.getProperty("KPI_SMS_SCHEDULE_ISABLE"));
改为:
Boolean AutoManaged = Boolean.valueOf(configure.getProperty("KPI_SMS_SCHEDULE_ISABLE"));

21. Array is stored directly
问题描述:字符串被直接存储
解决方法:public void setXXX(String str)
{
this.str = str;
} 改为:
public void setXXX(String str)
{
String myStr = str;
this.str = myStr;
}

22. System.out and System.err should not be used as loggers
问题描述:在catch中最好不要用System.out或System.err
解决方法:
try{
file.createNewFile();
}catch(Exception ex){
System.out.println(文件创建出错);
} 改为:
try{
file.createNewFile();
}catch(Exception ex){
log.error("", ex);
throw new Exception("文件创建出错:"+ex.getMessage());
}

23.Nonconstant string passed to execute method on an SQL statement
问题描述:直接以字符串的形式执行sql可能会引起sql注入的危险
解决方法:运用PreparedStatement代替Statement,用set方法把?替换为字符串
Connection con = null;
Statement stmt=null;
try{

if(operatorList == null || operatorList.size() == 0){
return;
}
if(resourceList == null || resourceList.size() == 0){
return;
}

con = this.getConnection();

stmt = con.createStatement();

String sql = "delete from " + this.getRightTable()
+ " where operatorid in (" + StringFunc.list_to_str(operatorList, ",", true) + ") "
+ " and resourceid in (" + StringFunc.list_to_str(resourceList, "

,", true) + ") "
+ " and operatortype=" + operatorType
+ " and resourcetype=" + resourceType;
if ("1".equals(isAccessType)){
sql+=" and accesstype="+SysCodes.accessType;
}

stmt.executeUpdate(sql);

https://www.wendangku.net/doc/7315194074.html,(sql);
}catch(Exception ex){
log.error("", ex);
throw new RuntimeException(ex.getMessage());
}finally{
if(stmt!=null){
try {
stmt.close();
} catch (SQLException e) {
log.error("", e);
}
}
}
改为:
Connection con = null;
PreparedStatement pStmt = null;
try{

if(operatorList == null || operatorList.size() == 0){
return;
}
if(resourceList == null || resourceList.size() == 0){
return;
}

con = this.getConnection();


String sql = "delete from " + this.getRightTable()
+ " where operatorid in (" + StringFunc.list_to_str(operatorList, ",", true) + ") "
+ " and resourceid in (" + StringFunc.list_to_str(resourceList, ",", true) + ") "
+ " and operatortype=? and resourcetype=?";
if ("1".equals(isAccessType)){
sql+=" and accesstype=?";
}
pStmt = con.prepareStatement(sql);
pStmt.setInt(1, operatorType);
pStmt.setInt(2, resourceType);
if ("1".equals(isAccessType)){
pStmt.setString(3, SysCodes.accessType);
}
pStmt.execute();

https://www.wendangku.net/doc/7315194074.html,(sql);
}catch(Exception ex){
log.error("", ex);
throw new RuntimeException(ex.getMessage());
}finally{
if(pStmt!=null){
try {
pStmt.close();
} catch (SQLException e) {
log.error("", e);
}
}
}



另外为了防止sonar报错需要注意:
1.包名,类名,字段名,函数名要命名规范
2.尽量避免类与类之间的循环依赖
2.不要catch NullPointerException错误
3.避免变量名和方法名重名,也要避免局部变量重命名和全局变量名重名
4.注意方法和类的长度,超过指定长度要进行提炼类或提炼函数,避免代码味道的出现

相关文档