格式:問題名字+問題出現的次數
資源未關閉,打開發現有兩處用到的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的形式,這個有待於以後學習。
不要寫空方法,除非這種情況: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成員是與類、靜態方法相聯繫的。
具體參考下面的18,我還沒理解
Primitives should not be boxed just for "String" conversion2
不要使用 4+" "這樣的方式將int值轉變爲字符串,而是使用 Integer.toString(4)這樣的方式。
就像Integer.parseInt("我是字符串")這樣,不要偷懶。
不要寫空類
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
VectorDeque instead of
StackHashMap instead of
HashtableStringBuilder instead of
StringBufferExit 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
來源:簡書
簡書著作權歸作者所有,任何形式的轉載都請聯繫作者獲得授權並註明出處。