sonar平臺代碼質量分析總結一

格式:問題名字+問題出現的次數

Resources should be closed2

資源未關閉,打開發現有兩處用到的IO流沒有關閉

Conditions should not unconditionally evaluate to "TRUE" or to "FALSE"1

if/else判斷裏出現了重複判斷,比如在if(a>10)的執行體裏面又判斷if(a<0),而後者肯定不會是true

Exception handlers should preserve the original exception13

處理異常的時候應該保留原始的異常情況,不要直接來個catch(Exception e)了事

Throwable.printStackTrace(...) should not be called7

不應該直接調用e.printStackTrace(),而是用Loggers來處理(就是打Log)。

Loggers的優勢是:Users are able to easily retrieve the logs.

The format of log messages is uniform and allow users to browse the logs easily.

Instance methods should not write to "static" fields6

不要用實例方法改變靜態成員,理想情況下,靜態變量只通過同步的靜態方法來改變

"public static" fields should be constant1

公共靜態成員應該加上final,也就是public static final 一般不分家

Thread.run() and Runnable.run() should not be called directly1

不應該直接調用Thread和Runnaale對象的run方法,直接調用run會使得run方法執行在當前線程,失去了開啓新線程的意義。但有時候可能會這樣做,下面有個例子。

Generic exceptions should never be thrown1

不太理解,大意是說不要直接拋Error,RuntimeException/Throwable/Exception這樣的通用的異常。我的具體應用是:throw new Error("Error copying database"),給出的建議是:Define and throw a dedicated exception instead of using a generic one(定義並拋出一個專用的異常來代替一個通用的異常)

Class variable fields should not have public accessibility64

類變量不要設置爲public,而是設爲private,再提供get和set方法。

Sections of code should not be "commented out"30

不要再註釋中出現大量的代碼段,會使代碼可讀性變差

Package declaration should match source file directory19

這個沒理解,包的聲明應該與源文件目錄匹配。

Utility classes should not have public constructors16

工具類不應該有公共的構造器,也就是說至少要有一個private的構造器,如果沒有,默認的構造器是public的。

The diamond operator ("<>") should be used12

在定義集合的時候,等號右邊的<>內不需要再寫上元素類型,直接空着就行。

Lambdas and anonymous classes should not have too many lines9

Lambdas表達式和匿名內部類不要寫太多行,一般最多寫20行。

Anonymous inner classes containing only one method should become lambdas8

只包含一個方法的匿名內部類應該寫成Lambdas表達式的形式,增強代碼可讀性

Try-with-resources should be used8

用Try-with-resources的形式取代try/catch/finally的形式,這個有待於以後學習。

Methods should not be empty7

不要寫空方法,除非這種情況:An abstract class may have empty methods, in order to provide default implementations for child classes.

Source files should not have any duplicated blocks7

源文件中不要出現任何重複的代碼段或行或字符串等。沒理解。

"switch case" clauses should not have too many lines6

"switch case" 每個case裏面的代碼不要太長,太長的話可以考慮寫個方法代替,主要是爲了增強代碼可讀性

Nested blocks of code should not be left empty6

嵌套代碼塊不要是空的,比如 if( a > 0 ) {  doSomething()  } else { },這時候應該把後面的else{}去掉。

Methods should not be too complex6

方法不要太複雜,否則難以理解和維護。

Unused private fields should be removed5

沒有使用的private的成員變量應該移除掉。

Dead stores should be removed5

沒有用到的本地變量或其他死存儲應該移除掉,也就是寫方法的時候,定義的變量如果後來發現根本用不到,要記得刪掉那行代碼。

"switch" statements should end with a "default" clause4

switch語句應該以default結束,這是一種defensive programming思想

Unused method parameters should be removed4

沒有用到的方法參數應該移除掉

Control flow statements "if", "for", "while", "switch" and "try" should not be nested too deeply4

if /for/while/try這樣的嵌套不要太複雜

Useless parentheses around expressions should be removed to prevent any misunderstanding3

沒有意義的括號不要隨便加,以免造成誤解,比如"="兩邊對象類型是相同的,就不要強轉。

"for" loop stop conditions should be invariant3

for循環的結果條件不能是變量,而應該是常量

"static" members should be accessed statically2

static成員是與類、靜態方法相聯繫的。

Catches should be combined2

具體參考下面的18,我還沒理解

Primitives should not be boxed just for "String" conversion2

不要使用 4+" "這樣的方式將int值轉變爲字符串,而是使用 Integer.toString(4)這樣的方式。

就像Integer.parseInt("我是字符串")這樣,不要偷懶。

Classes should not be empty2

不要寫空類

Unused local variables should be removed2

沒有用到的本地變量要刪掉

"entrySet()" should be iterated when both the key and value are needed2

直接看英文更直接:When only the keys from a map are needed in a loop, iterating the keySet makes sense. But when both the key and the value are needed, it's more efficient to iterate theentrySet, which will give access to both the key and value, instead.

也就是說,如果只需要Map的Key,那麼直接iterate這個Map的keySet就可以了,但是如果Key和value都需要,就iterate這個Map。具體看下面的19.

Method parameters, caught exceptions and foreach variables should not be reassigned2

方法參數/捕獲的異常/foreach的變量不應該被重新賦值。

Collection.isEmpty() should be used to test for emptiness2

當判斷集合是否爲空的時候,不要使用if (myCollection.size() == 0) 這樣的方式,而是使用if (myCollection.isEmpty()這樣的方式,後者性能更高。

Standard outputs should not be used directly to log anything2

標準輸出不直接打印任何東西,也就是打log的時候,不要使用System.out.println("My Message")這樣的方式,而是使用logger.log("My Message")這種方式。

Generic wildcard types should not be used in return parameters1

通配符不應該出現在返回聲明中。比如這句:List <? extends Animal>getAnimals(){...}, 我們無法知道“是否可以把a Dog, a Cat 等加進去”,等之後用到這個方法的時候,我們沒必要去考慮這種問題(前面引號裏面的)。

Synchronized classes Vector, Hashtable, Stack and StringBuffer should not be used1

不要使用同步的Vector/HashTable/Stack/StringBuffer等。在早期,出於線程安全問題考慮,java API 提供了這些類。但是同步會極大影響性能,即使是在同一個線程中使用他們。

通常可以這樣取代:

ArrayList  or  LinkedList   instead of  Vector

Deque  instead of  Stack

HashMap  instead of  Hashtable

StringBuilder  instead of  StringBuffer

Exit methods should not be called

儘量不要調用system.exit()方法。

Local Variables should not be declared and then immediately returned or thrown7

本地變量如果賦值之後直接return了,那就直接return本地變量的賦值語句。

Field names should comply with a naming convention6

命名要規範

Local variable and method parameter names should comply with a naming convention6

命名要規範

String literals should not be duplicated5

字符串不應該重複,如果多次用到同一字符串,建議將該字符串定義爲字符串常量,再引用。

Return of boolean expressions should not be wrapped into an "if-then-else" statement3

不要寫if (  a > 4  ) {  return false  } else { return true }這樣的代碼,直接寫return a > 4。

Static non-final field names should comply with a naming convention2

命名要規範

Modifiers should be declared in the correct order2

修飾符等要按約定俗成的順序書寫 ,例如,寫成public static 而不是static public 

The members of an interface declaration or class should appear in a pre-defined order2

與前面的一個問題類似,根據Oracle定義的Java代碼規範中,不同代碼的出現位置應該如下所示:

class and instance variables--Constructors--Methods

Array designators "[]" should be on the type, not the variable2

數組的括號要寫在類型後面,而不是變量後面,例如 int[] a 而不是int a[]

Multiple variables should not be declared on the same line1

不要在同一行定義多個變量

"switch" statements should have at least 3 "case" clauses1

當至少有3種或者3種以上的情況時,才考慮用switch,否則用if/else的形式。

Overriding methods should do more than simply call the same method in the super class1

既然在子類中重寫了父類的某個方法,那就再這個方法中做些與父類方法不同的事情,否則沒必要重寫。

Statements should be on separate lines1

不要把這樣的代碼寫在同一行:if(someCondition)    doSomething();而是應該寫成下面的形式

if(someCondition) {

doSomething()

}

Method names should comply with a naming convention1

命名要規範

"TODO" tags should be handle    TODO標籤要及時處理,該做的事情不要忘了做

 

 

 

部分規則詳細說明

1.The members of an interface declaration or class should appear in a pre-defined order


正確的順序如下所示:靜態成員變量→成員變量→構造器→方法

public class Foo{

public static final int OPEN = 4;  //Class and instance variables

private int field = 0;

public Foo() {...}    //Constructors

public boolean isTrue() {...}    //Methods

}

2.The diamond operator ("<>") should be used

Noncompliant Code Example:不規範的示例

List<String>  strings = new ArrayList<String>();  // Noncompliant

Map<String, List<Integer>> map = new HashMap<String, List<Integer>>();  // Noncompliant

Compliant Solution :規範的示例

List<String> strings = new ArrayList<>();

Map<String, List<Integer>> map = new HashMap<>();

3.Sections of code should not be "commented out"

代碼片段不應該出現在註釋中,這樣會bloat程序,可讀性變差

Programmers should not comment out code as it bloats programs and reduces readability.

Unused code should be deleted and can be retrieved from source control history if required.

4.Utility classes should not have public constructors

工具類不應該有public的構造器,也就是工具類至少要定義一個non-public的構造器

Utility classes, which are a collection of static members, are not meant to be instantiated. Even abstract utility classes, which can be extended, should not have public constructors.

Java adds an implicit public constructor to every class which does not define at least one explicitly. Hence, at least one non-public constructor should be defined.

class StringUtils { // Noncompliant Code Example

    public static String concatenate(String s1, String s2) {

          return s1 + s2;

    }

}

class StringUtils { //Compliant Solution

    private StringUtils() {

    }

    public static String concatenate(String s1, String s2) {

    return s1 + s2;

    }

}

5."public static" fields should be constant

公共的靜態成員應該加上final來修飾

There is no good reason to declare a field "public" and "static" without also declaring it "final". Most of the time this is a kludge to share a state among several objects. But with this approach, any object can do whatever it wants with the shared state, such as setting it to null.

public static Foo foo = new Foo();//不規範的

public static final Foo FOO = new Foo();//規範的

6.Class variable fields should not have public accessibility

public class MyClass {

public static final int SOME_CONSTANT = 0;    // Compliant - constants are not checked

public String firstName;                      // Noncompliant

}

public class MyClass {

public static final int SOME_CONSTANT = 0;    // Compliant - constants are not checked

private String firstName;                      // Compliant

public String getFirstName() {

return firstName;

}

public void setFirstName(String firstName) {

this.firstName = firstName;

}

}

7.Static non-final field names should comply with a naming convention

public final class MyClass {//Noncompliant Code Example

      private static String foo_bar;

}

class MyClass {//Compliant Solution

private static String fooBar;

}

8."switch" statements should have at least 3 "case" clauses

當有3種或3種情況以上的時候,才用switch,否則用if/else

switch statements are useful when there are many different cases depending on the value of the same expression.

For just one or two cases however, the code will be more readable with if statements.

9.String literals should not be duplicated

prepare("action1");     // Noncompliant - "action1" is duplicated 3 times

execute("action1");

release("action1");


private static final String ACTION_1 = "action1";  // Compliant

prepare(ACTION_1);                                            // Compliant

execute(ACTION_1);

release(ACTION_1);

10.Return of boolean expressions should not be wrapped into an "if-then-else" statement

if (expression) {//Noncompliant Code Example

      return true;

} else {

     return false;

}


return expression;//Compliant Solution

return !!expression;

11.Method parameters, caught exceptions and foreach variables should not be reassigned

方法參數,捕獲的異常,foreach裏的變量,都不應該重新賦值

 

class MyClass {//Noncompliant Code Example:不規範代碼示例

    public String name;

    public MyClass(String name) {

            name = name;          // Noncompliant - useless identity assignment

    }

    public int add(int a, int b) {

        a = a + b;                // Noncompliant

        return a;                 // Seems like the parameter is returned as is, what is the point?

   }

    public static void main(String[] args) {

        MyClass foo = new MyClass();

        int a = 40;

        int b = 2;

        foo.add(a, b);                  // Variable "a" will still hold 40 after this call

    }

}


class MyClass {//Compliant Solution:規範代碼示例

    public String name;

    public MyClass(String name) {

         this.name = name;              // Compliant

    }

    public int add(int a, int b) {

        return a + b;                  // Compliant

    }

    public static void main(String[] args) {

    MyClass foo = new MyClass();

        int a = 40;

        int b = 2;

        foo.add(a, b);

     }

}

12.Local Variables should not be declared and then immediately returned or thrown

Noncompliant Code Example:不規範代碼示例

public long computeDurationInMilliseconds() {

long duration = (((hours * 60) + minutes) * 60 + seconds ) * 1000 ;

return duration;

}

public void doSomething() {

RuntimeException myException = new RuntimeException();

throw myException;

}


Compliant Solution:規範代碼示例

public long computeDurationInMilliseconds() {

return (((hours * 60) + minutes) * 60 + seconds ) * 1000 ;

}

public void doSomething() {

throw new RuntimeException();

}

13.Thread.run() and Runnable.run() should not be called directly

The purpose of theThread.run()andRunnable.run()methods is to execute code in a separate, dedicated thread. Calling those methods directly doesn't make sense because it causes their code to be executed in the current thread.

Thread和Runnable裏面的run方法設計的目的是讓run方法裏面的代碼在不同的線程中執行。如果直接調用run方法,就會導致run方法裏的代碼在當前線程中執行,失去意義

Noncompliant Code Example:不規範的代碼示例

Thread myThread = new Thread(runnable);

myThread.run(); // Noncompliant


Compliant Solution:規範代碼示例

Thread myThread = new Thread(runnable);

myThread.start(); // Compliant

這部分內容爲個人理解,可以略過

但在有些情況,也會直接調用Runnable的run方法,

下面這個postTaskSafely方法會保證task永遠在主線程中執行

public static void postTaskInMainThread(Runnable task) {

     int curThreadId= android.os.Process.myTid();//得到當前線程的id

    if(curThreadId==getMainThreadId()) {// 如果當前線程是主線程

            task.run();//直接執行

    }else{// 如果當前線程不是主線程

        getMainThreadHandler().post(task);//用主線程的Handler來post

}

14.Lambdas and anonymous classes should not have too many lines

Anonymous classes and lambdas (with Java 8) are a very convenient and compact way to inject a behavior without having to create a dedicated class. But those anonymous inner classes and lambdas should be used only if the behavior to be injected can be defined in a few lines of code, otherwise the source code can quickly become unreadable.

anonymous class number of lines : at most 20

15.Resources should be closed:該關閉的一定記得關閉

Java's garbage collection cannot be relied on to clean up everything. Specifically, connections, streams, files and other classes that implement theCloseableinterface or it's super-interface,AutoCloseable, must be manually closed after creation. Failure to do so will result in a resource leak which could bring first the application and then perhaps the box it's on to their knees.

Noncompliant Code Example:不規範的代碼示例

    OutputStream stream = null;

    try{

        for (String property : propertyList) {

        stream = new FileOutputStream("myfile.txt");  // Noncompliant

        // ...

        }

    }catch(Exception e){

        // ...

    }finally{

        stream.close();  // Multiple streams were opened. Only the last is closed.

    }


Compliant Solution:規範代碼示例

    OutputStream stream = null;

    try{

        stream = new FileOutputStream("myfile.txt");

        for (String property : propertyList) {

            // ...

        }

   }catch(Exception e){

        // ...

   }finally{

       stream.close();

   }

16.Exception handlers should preserve the original exception

Noncompliant Code Example:不規範的代碼示例

// Noncompliant - exception is lost

try { /* ... */ } catch (Exception e) { LOGGER.info("context"); }

// Noncompliant - exception is lost (only message is preserved)

try { /* ... */ } catch (Exception e) { LOGGER.info(e.getMessage()); }

// Noncompliant - exception is lost

try { /* ... */ } catch (Exception e) { throw new RuntimeException("context"); }


Compliant Solution:規範的代碼示例

try { /* ... */ } catch (Exception e) { LOGGER.info(e); }

try { /* ... */ } catch (Exception e) { throw new RuntimeException(e); }

try {

/* ... */

} catch (RuntimeException e) {

doSomething();

throw e;

} catch (Exception e) {

// Conversion into unchecked exception is also allowed

throw new RuntimeException(e);

}

17.Catches should be combined

Since Java 7 it has been possible to catch multiple exceptions at once. Therefore, when multiplecatchblocks have the same code, they should be combined for better readability.

Note that this rule is automatically disabled when the project'ssonar.java.sourceis lower than7.

Noncompliant Code Example:不規範代碼示例

catch (IOException e) {

    doCleanup();

    logger.log(e);

}catch (SQLException e) { //Noncompliant

    doCleanup();

    logger.log(e);

 }catch (TimeoutException e) {  // Compliant; block contents are different

     doCleanup();

     throw e;

 }


Compliant Solution:規範代碼示例

catch (IOException|SQLException e) {

    doCleanup();

    logger.log(e);

 }catch (TimeoutException e) {

    doCleanup();

    throw e;

}

18."entrySet()" should be iterated when both the key and value are needed

Noncompliant Code Example:不規範的代碼示例

public void doSomethingWithMap(Map map) {

for (String key : map.keySet()) {  // Noncompliant; for each key the value is retrieved

Object value = map.get(key);

// ...

}   

}   


Compliant SolutionL:規範代碼示例

public void doSomethingWithMap(Map map) {

for (Map.Entry entry : map.entrySet()) {

String key = entry.getKey();

Object value = entry.getValue();

// ...

}   

}   



作者:maxwellyue
鏈接:https://www.jianshu.com/p/b50f01eeba4d
來源:簡書
簡書著作權歸作者所有,任何形式的轉載都請聯繫作者獲得授權並註明出處。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章