月眸


Sonar常见问题解决方案

毛毛小妖 2019-03-26 1085浏览 8条评论
首页/ 正文
分享到: / / / /

一、阻断

1、Close this"FileInputStream" in a "finally" clause.

在流使用完之后,应该关闭该流,finally代码块中,应该要对每个流进行单独关闭,而不能统一写在一个try-catch代码中。而且还要遵守一个原则:先打开的后关闭,后打开的先关闭。

2、A"NullPointerException" could be thrown; "tom" is nullablehere

解决方法很简单,在使用变量时先判断是否为null

二、严重

1、Define and throw a dedicated exception instead of using a generic one

不要在定义方法时直接throws Exception,而要用try{}catch(FileNotFoundException e){}明确抛出异常类型

2、Removethis hard-coded password 

移除代码里硬编码的密码信息。会有少许的误判的情况,一般是变量包含:PWD或者password,所以如果真的不是硬编码,可以考虑更换变量名称,比如PWD改PW等等。

3、Eitherlog or rethrow this exception

使用catch捕捉到异常之后,使用log方式或者throw异常的方式解决。如果业务上真的没有throw或者记录日志的话,可以使用log.debug的方式填充来解决问题。而不是使用system.out来输出日志。

4、Makethis IP "127.0.0.1" address configurable

将一些写死的内容放到配置文件里面

5、Make this"public static JSAPI" field final 

如果你将这个变量设置为public访问方式,同时又是静态Static方式,就要考虑将它设置为final了,因为这个是共享变量,其它类可以随时随地将它设置为别的值。所以如果是只是当前类使用,可以考虑将公开访问方式改为私有。

6、Makethe enclosing method "static" or remove this set

见代码:

public class MyClass {
  private static int count = 0;
  public void doSomething() {
    //...
    count++;  // Noncompliant
  }
}

 

不要使用非静态方法去更新静态字段,这样很难获得正确的结果,如果有多个类实例和/或多个线程,则很容易导致错误。理想情况下,静态字段仅从同步静态方法中更新。

7、Override"equals(Object obj)" to comply with the contract of the"compareTo(T o)" method

如果重写了compareTo方法,同时也应重写equals方法。

8、Make"body" transient or serializable. 

public class Address {
  //...
}

public class Person implements Serializable {

  private static final long serialVersionUID = 1905122041950251207L;

  private String name;
  private Address address;  // Noncompliant; Address isn't serializable
}

 

如果person已经序列化,其成员变量Address也进行序列化。不然转化时会有问题。

9、 Floating point numbers should not be tested for equality

浮点类型的数字,不要通过==或者!=方式其它类型比较,因为浮点是不精确的,所以在比较时,会进行类型升级升级原则如下:

·  如果运算符任意一方的类型为double,则另一方会转换为double

·  否则,如果运算符任意一方的类型为float,则另一方会转换为float

·  否则,如果运算符任意一方的类型为long,则另一方会转换为long

·  否则,两边都会转换为int
以下的方式得到的结果都是false。

float myNumber = 3.146;

if ( myNumber == 3.146f ) { //Noncompliant. Because of floating point imprecision, this will be false

if ( myNumber != 3.146f ) { //Noncompliant. Because of floating point imprecision, this will be true

if (myNumber < 4 || myNumber > 4) { // Noncompliant; indirect  

float zeroFloat = 0.0f;

if (zeroFloat == 0) {  // Noncompliant. Computations may end up with a value close but not equal to zero.

}

 

所以,要比较浮点数是否相等,需要做的事情是:

 排除NaN和无穷

在精度范围内进行比较

正确的例子:

public boolean isEqual(double a, double b) {
    if (Double.isNaN(a) || Double.isNaN(b) || Double.isInfinite(a) || Double.isInfinite(b)) {
       return false;
    }
    return (a - b) < 0.001d;
}

10、Thiscall to "contains()" may be a performance hot spot if the collectionis large. 

如果collection的记录数非常大的话,它的contains方法的时间复杂度是很高的。所以开发过程中要注意这一点。

11、Call the method Thread.start() to execute the content of the run() method in a dedicated thread.

在启动线程时,要使用start()方法,而不是run()方法。因为run()方法只是一个普通的方法,并不会启动线程。start()方法才是线程的正确打开方式。在使用线程时最好不要显示的创建线程,而是使用线程池,因为线程池优化的更好,可以避免cpu资源耗尽。

12、数据精度问题

在进行浮点型或double类型比较的时候不能直接比较,比如要判断变量是否等于0,不能这样写:double a = getVal(); if(a==0d){//......},因为a这个变量可能是有小数点的,比如0.00000001,直接比较会得不到想要的结果,可以这样写:if(a<0.0001),即可达到目的。

 13、js字符替换

Js中要替换字符串中某些字符的时候,会用到replace()方法,这个时候往往会不小心用错。如果要替换首次出现的字符,用str.replace(“旧字符串”,"新字符串")。如果要全部替换的话这个是不对的,应该这样使用:str.replace(/旧字符串/g,"新字符串")

14、不要频繁的创建对象的引用

经常在代码中会循环一个集合,然后赋值给另外一个集合,通常我们会这样写:

List<Person> list = new ArrayList<Person>();
for(Member member : memberList){
    Person person = new Person();
    person.setName(member.getName());
    person.setAge(member.getAge());
    List.add(person);
}

这样写是没有问题的,但是Person person = new Person();这句代码会频繁的创建新的引用,消耗内存。更好的写法是只创建一个对象引用,像下面这样:

List<Person> list = new ArrayList<Person>();
Person person = null;
for(Member member : memberList){
    person = new Person();
    person.setName(member.getName());
    person.setAge(member.getAge());
    List.add(person);
}

15、java数据类型的使用

Java给我们提供了8种基本数据类型,我们在定义变量的类型时如果能确定是什么类型的最好定义成相应的类型,比如数量相关的就定义成int,日期类型的就定义成Date。而不是为了省事儿全部定义成String类型的,因为String底层是个数组,在对String类型的数据进行比较时,会遍历数组一位一位的比较,效率较慢。

16、路径分隔符

有时候在代码中会涉及到文件路径的问题,经常会这样写:

File file = new File(directoryName + "\\" + fileName);

这句话看似没问题,但是在其他平台上可能就会出错,因为不同平台的文件分割符是有区别的。我们应该用File.separator来代替\\。所以正确的写法应该是这样:

File file = new File(directoryName + File.separator + fileName);

17、git提交代码问题

有时候我们使用windows的代码eclipse修改了一个文件,但是在提交代码的时候发现有很多文件都被提交了,这是因为服务器是linux系统的,不同操作系统使用的换行符是不一样的。所以我们可以打开git命令行执行一下以下命令之后再提交即可:

git config --global core.autocrlf false
git config --global core.filemode false
git config --global core.safecrlf true

18、String,StringBuffer,StringBuilder的使用

在代码中经常会用到字符串拼接,这里说一下他们的区别:
String:适用于少量的字符串操作的情况
StringBuilder:适用于单线程下进行大量操作的情况
StringBuffer:适用多线程下进行大量操作的情况

最后修改:2019-03-26 17:12:11 © 著作权归作者所有
如果觉得我的文章对你有用,请随意赞赏
扫一扫支付

上一篇

发表评论

说点什么吧~

评论列表

匿名用户 2019-04-28 15:07:54

“不要频繁的创建对象的引用”是什么意思呢?

回复