PMD規則之Design Rules

·  UseSingleton: If you have a class that has nothing but static methods, consider making it a Singleton. Note that this doesn't apply to abstract classes, since their subclasses may well include non-static methods. Also, if you want this class to be a Singleton, remember to add a private constructor to prevent instantiation.

翻譯  使用單例:如果有一個類包含的只有靜態方法,可以考慮做成單例的。注意這個規則不適用於抽象類,因爲它們的子類可能包含非靜態方法。還有,如果你想把一個類做成單例的,記得寫一個私有的構造器以阻止外部實例化。

·  SimplifyBooleanReturns: Avoid unnecessary if..then..else statements when returning a boolean.

翻譯  簡化布爾量的返回:避免在返回布爾量時寫不必要的if..then..else表達式。

代碼示例:

public class Foo {

  private int bar =2;

  public boolean isBarEqualsTo(int x) {

    // this bit of code

    if (bar == x) {

     return true;

    } else {

     return false;

    }

    // 上面可以簡化爲:

    // return bar == x;

  }

}

·  SimplifyBooleanExpressions: Avoid unnecessary comparisons in boolean expressions - this complicates simple code.

翻譯  簡化布爾表達式:避免布爾表達式之間無用的比較——只會使代碼複雜化

代碼示例:

public class Bar {

 // 下面可以簡化爲: bar = isFoo();

 private boolean bar = (isFoo() == true);

 

 public isFoo() { return false;}

}

·  SwitchStmtsShouldHaveDefault: Switch statements should have a default label.

翻譯  Switch表達式應該有default

·  AvoidDeeplyNestedIfStmts: Deeply nested if..then statements are hard to read.

翻譯  避免深度嵌套的if表達式:深度嵌套的if..then表達式難以閱讀

·  AvoidReassigningParameters: Reassigning values to parameters is a questionable practice. Use a temporary local variable instead.

翻譯  避免給參數重新賦值:給傳入方法的參數重新賦值是一種需要商榷的行爲。使用臨時本地變量來代替。

·  SwitchDensity: A high ratio of statements to labels in a switch statement implies that the switch statement is doing too much work. Consider moving the statements into new methods, or creating subclasses based on the switch variable.

翻譯  密集的switchswitch表達式的case塊中出現很高比例的表達式語句表明switch表達式做了太多的工作。考慮將表達式語句寫進一個新的方法,或者創建基於switch變量的子類。

代碼示例:

public class Foo {

 public void bar(int x) {

   switch (x) {

     case 1: {

       // lots of statements

       break;

     } case 2: {

       // lots of statements

       break;

     }

   }

 }

}

·  ConstructorCallsOverridableMethod: Calling overridable methods during construction poses a risk of invoking methods on an incompletely constructed object and can be difficult to discern. It may leave the sub-class unable to construct its superclass or forced to replicate the construction process completely within itself, losing the ability to call super(). If the default constructor contains a call to an overridable method, the subclass may be completely uninstantiable. Note that this includes method calls throughout the control flow graph - i.e., if a constructor Foo() calls a private method bar() that calls a public method buz(), this denotes a problem.

翻譯  構造器調用了可重寫的方法:在構造器中調用可被覆蓋的方法可能引發在一個尚未構造完成的對象上調用方法的風險,而且是不易辨識的。它會使得子類不能構建父類或者自己強制重複構建過程,失去調用super()方法的能力。如果一個默認的構造器包含一個對可重寫方法的調用,子類可能完全不能被實例化。注意這也包含在整個控制流圖上的方法調用——例如:如果構造器Foo()調用了私有方法bar(),而bar()又調用了公開的方法buz(),這就會導致問題。

代碼示例:

public class SeniorClass {

  public SeniorClass(){

      toString(); //may throw NullPointerException if overridden

  }

  public String toString(){

    return "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();

  }

}

·  AccessorClassGeneration: Instantiation by way of private constructors from outside of the constructor's class often causes the generation of an accessor. A factory method, or non-privitization of the constructor can eliminate this situation. The generated class file is actually an interface. It gives the accessing class the ability to invoke a new hidden package scope constructor that takes the interface as a supplementary parameter. This turns a private constructor effectively into one with package scope, and is challenging to discern.

翻譯  存取器類生成:從一個具有私有構建器的類的外部實例化這個類通常會導致存取器的生成。工廠方法,或者非私有化的構造器可以避免這個情況。生成的類文件事實上是一個接口。它賦予訪問類調用一個新的隱藏的包範圍的構建器並把這個接口作爲補充參數的能力。這樣就把私有的構造器有效地轉換爲一個包範圍的構建器,而且是不易覺察的。

代碼示例:

public class Outer {

 void method(){

  Inner ic = new Inner();//Causes generation of accessor class

 }

 public class Inner {

  private Inner(){}

 }

}

·  FinalFieldCouldBeStatic: If a final field is assigned to a compile-time constant, it could be made static, thus saving overhead in each object at runtime.

翻譯  final類型的域可以同時是static的:如果一個final類型的域在編譯時被賦值爲常量,它也可以是static的,那樣就在每個對象運行時節省開支。

·  CloseResource: Ensure that resources (like Connection, Statement, and ResultSet objects) are always closed after use.

翻譯  關閉資源:確保這些資源(譬如:Connection,Statement,ResultSet對象)總在使用後被關閉。

·  NonStaticInitializer: A nonstatic initializer block will be called any time a constructor is invoked (just prior to invoking the constructor). While this is a valid language construct, it is rarely used and is confusing.

翻譯  非靜態的初始化器:非靜態的初始化塊將在構造器被調用的時候被訪問(優先於調用構造器)。這是一個有效的語言結構,但使用很少且易造成迷惑。

代碼示例:

public class MyClass {

 // this block gets run before any call to a constructor

 {

  System.out.println("I am about to construct myself");

 }

}

·  DefaultLabelNotLastInSwitchStmt: By convention, the default label should be the last label in a switch statement.

翻譯  switch表達式中default塊應該在最後:按照慣例,default標籤應該是switch表達式的最後一個標籤。

·  NonCaseLabelInSwitchStatement: A non-case label (e.g. a named break/continue label) was present in a switch statement. This legal, but confusing. It is easy to mix up the case labels and the non-case labels.

翻譯  switch表達式中沒有case標籤:在switch表達式中沒有case,是合法的,但是容易造成迷惑。容易將case標籤和非case標籤混淆。

·  OptimizableToArrayCall: A call to Collection.toArray can use the Collection's size vs an empty Array of the desired type.

翻譯  優化toArray調用:調用Collection.toArray時使用集合的規模加上目標類型的空數組作爲參數。

代碼示例:

class Foo {

 void bar(Collection x) {

   // A bit inefficient

   x.toArray(new Foo[0]);

   // Much better; this one sizes the destination array, avoiding

   // a reflection call in some Collection implementations

   x.toArray(new Foo[x.size()]);

 }

}

·  BadComparison: Avoid equality comparisons with Double.NaN - these are likely to be logic errors.

翻譯  錯誤的比較:避免Double.NaN的相等性比較-這些可能是邏輯錯誤

·  EqualsNull: Inexperienced programmers sometimes confuse comparison concepts and use equals() to compare to null.

翻譯  等於空:經驗缺乏的程序員有時候會迷惑於相等性概念,拿equals()方法和null比較

·  ConfusingTernary: In an "if" expression with an "else" clause, avoid negation in the test. For example, rephrase: if (x != y) diff(); else same(); as: if (x == y) same(); else diff(); Most "if (x != y)" cases without an "else" are often return cases, so consistent use of this rule makes the code easier to read. Also, this resolves trivial ordering problems, such as "does the error case go first?" or "does the common case go first?".

翻譯  令人迷惑的三種性:在if表達式伴隨else子句時,避免在if測試中使用否定表達。例如:不要使用if (x != y) diff(); else same()這種表述,而應該使用if (x == y) same(); else diff(),大多數時候使用if(x!=y)形式時不包含else分句,所以一貫地使用此規則能讓代碼更易於閱讀。此外,這也解決了一個細節的排序問題,比如“應該是判斷爲false的代碼塊在前面?”,還是“判斷通過的代碼塊在前?”

·  InstantiationToGetClass: Avoid instantiating an object just to call getClass() on it; use the .class public member instead.

翻譯  通過getClass實例化:避免通過訪問getClass()實例化對象,使用.class這個公共屬性代替。

·  IdempotentOperations: Avoid idempotent operations - they are have no effect.

翻譯  冪等性操作:避免冪等性操作-它們不起任何作用

冪等性操作,同樣的操作無論執行多少次,其結果都跟第一次執行的結果相同。

代碼示例:

public class Foo {

 public void bar() {

  int x = 2;

  x = x;

 }

}

·  SimpleDateFormatNeedsLocale: Be sure to specify a Locale when creating a new instance of SimpleDateFormat.

翻譯  SimpleDateFormat類需要本地參數:確保在創建SimpleDateFormat類的實例時指定了Locale參數

·  ImmutableField: Identifies private fields whose values never change once they are initialized either in the declaration of the field or by a constructor. This aids in converting existing classes to immutable classes.

翻譯  不變域:識別出一旦被聲明就賦值或通過構造器賦值後就從不改變的私有域,它們將存在的類變成了不變類。這樣的域可以是final

代碼示例:

public class Foo {

  private int x; // could be final

  public Foo() {

      x = 7;

  }

  public void foo() {

     int a = x + 2;

  }

}

·  UseLocaleWithCaseConversions: When doing a String.toLowerCase()/toUpperCase() call, use a Locale. This avoids problems with certain locales, i.e. Turkish.

翻譯  大小寫轉換時使用Locale:當訪問String.toLowerCase()/toUpperCase()時使用Locale參數,這樣可以避免某些特定的本地化問題,比如土耳其語

·  AvoidProtectedFieldInFinalClass: Do not use protected fields in final classes since they cannot be subclassed. Clarify your intent by using private or package access modifiers instead.

翻譯  避免在final類中使用protected域:因爲final類型的class不能被繼承,所以不要使用protected域,通過使用private或包訪問符來代替以修正你的意圖。

·  AssignmentToNonFinalStatic: Identifies a possible unsafe usage of a static field.

翻譯  給一個非finalstatic類型賦值:識別出一個非安全的static域使用

代碼示例:

public class StaticField {

   static int x;

   public FinalFields(int y) {

    x = y; // unsafe

   }

}

·  MissingStaticMethodInNonInstantiatableClass: A class that has private constructors and does not have any static methods or fields cannot be used.

翻譯  在不可實例化類中缺少靜態方法:一個具有私有構造器且沒有任何靜態方法或靜態變量的類不能被使用

·  AvoidSynchronizedAtMethodLevel: Method level synchronization can backfire when new code is added to the method. Block-level synchronization helps to ensure that only the code that needs synchronization gets it.

翻譯  避免方法級的同步:當爲一個同步的方法加入新代碼時可能發生意外。塊級別的同步可以確保內含真正需要同步的代碼。

·  MissingBreakInSwitch: A switch statement without an enclosed break statement may be a bug.

翻譯  switch塊中缺少breakswitch表達式缺少內含的break塊可能是bug

·  UseNotifyAllInsteadOfNotify: Thread.notify() awakens a thread monitoring the object. If more than one thread is monitoring, then only one is chosen. The thread chosen is arbitrary; thus it's usually safer to call notifyAll() instead.

翻譯  使用notifyAll代替notify: Thread.notify()喚醒監控對象的線程。如果多餘一個線程在監控中,只會有一個被選擇。這個線程的選擇是隨機的,因此調用notifyAll()代替它更安全。

·  AvoidInstanceofChecksInCatchClause: Each caught exception type should be handled in its own catch clause.

翻譯  避免在catch塊中使用instanceof:每個產生的異常類型都應該在自己的catch塊中被處理。

·  AbstractClassWithoutAbstractMethod: The abstract class does not contain any abstract methods. An abstract class suggests an incomplete implementation, which is to be completed by subclasses implementing the abstract methods. If the class is intended to be used as a base class only (not to be instantiated direcly) a protected constructor can be provided prevent direct instantiation.

翻譯  抽象類沒有抽象方法:抽象類沒有包含抽象方法,抽象類建議未完成的方法實現,這個方法在子類中被完成。如果類意圖被用作基礎類(不被直接實例化),一個protected的構造器就能提供對直接實例化的阻止。

·  SimplifyConditional: No need to check for null before an instanceof; the instanceof keyword returns false when given a null argument.

翻譯  簡化條件:在使用instanceof之間不需要null校驗,當給予一個null作爲參數時,instanceof返回false

·  CompareObjectsWithEquals: Use equals() to compare object references; avoid comparing them with ==.

翻譯  對象相等性比較:使用equals()比較對象的引用,避免使用”==”來比較

·  PositionLiteralsFirstInComparisons: Position literals first in String comparisons - that way if the String is null you won't get a NullPointerException, it'll just return false.

翻譯  把字面量放在比較式的前面:在字符串比較時,將字面量放在前面-這種方法能夠避免當字符串爲空時的空指針異常,只是返回false

·  UnnecessaryLocalBeforeReturn: Avoid unnecessarily creating local variables

翻譯  return之前不必要的本地變量:避免創建不必要的本地變量

代碼示例:

public class Foo {

    public int foo() {

      int x = doSomething();

      return x;  // instead, just 'return doSomething();'

    }

  }

·  NonThreadSafeSingleton: Non-thread safe singletons can result in bad state changes. Eliminate static singletons if possible by instantiating the object directly. Static singletons are usually not needed as only a single instance exists anyway. Other possible fixes are to synchronize the entire method or to use an initialize-on-demand holder class (do not use the double-check idiom). See Effective Java, item 48.

翻譯  非線程安全的單例:非線程安全的單例可以導致錯誤的狀態轉換。如果可能通過直接實例化消除靜態的單例.因爲事實上只存在一個實例,所以靜態單例一般是不需要的。另外的解決辦法是同步實際的方法或者使用一個按需實例化的持有類(不要使用雙重檢查機制)。請參閱:Effective Java,48章。

代碼示例:

private static Foo foo = null;

//multiple simultaneous callers may see partially initialized objects

public static Foo getFoo() {

    if (foo==null)

        foo = new Foo();

    return foo;

}

·  UncommentedEmptyMethod: Uncommented Empty Method finds instances where a method does not contain statements, but there is no comment. By explicitly commenting empty methods it is easier to distinguish between intentional (commented) and unintentional empty methods.

翻譯  不含註釋的空方法:不含註釋的空方法就是說一個方法內部沒有任何程序代碼也沒有註釋。通過明確的註釋空方法能夠容易的區分有潛在意向的和無意向的空方法。

·  UncommentedEmptyConstructor: Uncommented Empty Constructor finds instances where a constructor does not contain statements, but there is no comment. By explicitly commenting empty constructors it is easier to distinguish between intentional (commented) and unintentional empty constructors.

翻譯  不含註釋的空構造器:不含註釋的空構造器就是說一個構造器內部沒有任何程序代碼也沒有註釋。通過明確的註釋空構造器能夠容易的區分有潛在意向的和無意向的空構造器

·  AvoidConstantsInterface: An interface should be used only to model a behaviour of a class: using an interface as a container of constants is a poor usage pattern.

翻譯  避免常量接口:接口僅僅是應該用來建模類的行爲的:使用接口作爲常量的容器是一種劣質的用法。

·  UnsynchronizedStaticDateFormatter: SimpleDateFormat is not synchronized. Sun recomends separate format instances for each thread. If multiple threads must access a static formatter, the formatter must be synchronized either on method or block level.

翻譯  不要同步靜態的DateFormat類:SimpleDateFormat是非同步的。Sun公司建議對每個線程單獨的format實例。如果多線程必須訪問一個靜態formatterformatter必須在方法或塊級別同步。

代碼示例:

public class Foo {

    private static final SimpleDateFormat sdf = new SimpleDateFormat();

    void bar() {

        sdf.format(); // bad

    }

    synchronized void foo() {

        sdf.format(); // good

    }

}

·  PreserveStackTrace: Throwing a new exception from a catch block without passing the original exception into the new exception will cause the true stack trace to be lost, and can make it difficult to debug effectively.

翻譯  保留追蹤棧:在一個catch塊中拋出一個新的異常卻不把原始的異常傳遞給新的異常會導致真正的追蹤信息棧丟失,而且導致難以有效的調試。

代碼示例:

public class Foo {

    void good() {

        try{

            Integer.parseInt("a");

        } catch(Exception e){

            throw new Exception(e);

        }

    }

    void bad() {

        try{

            Integer.parseInt("a");

        } catch(Exception e){

            throw new Exception(e.getMessage());

        }

    }

}

·  UseCollectionIsEmpty: The isEmpty() method on java.util.Collection is provided to see if a collection has any elements. Comparing the value of size() to 0 merely duplicates existing behavior.

翻譯  使用集合類的isEmpty方法:java.util.Collection類的isEmpty方法提供判斷一個集合類是否包含元素。不要是使用size()0比較來重複類庫已經提供的方法。

public class Foo {

           void good() {

              List foo = getList();

                 if (foo.isEmpty()) {

                      // blah

                 }

          }

//下面是不推薦的方式

          void bad() {

              List foo = getList();

                      if (foo.size() == 0) {

                            // blah

                      }

                }

      }

·  ClassWithOnlyPrivateConstructorsShouldBeFinal: A class with only private constructors should be final, unless the private constructor is called by a inner class.

翻譯  類只包含私有的構造器應該是final的:一個類只包含私有的構造器應該是final的,除非私有構造器被一個內部類訪問。

public class Foo {  //Should be final

    private Foo() { }

}

·  EmptyMethodInAbstractClassShouldBeAbstract: An empty method in an abstract class should be abstract instead, as developer may rely on this empty implementation rather than code the appropriate one.

翻譯  一個抽象類中的空方法也應該是抽象的:一個抽象類中的空方法也應該是抽象的,因爲開發者有可能會信任這個空的實現而不去編寫恰當的代碼。

·  SingularField: This field is used in only one method and the first usage is assigning a value to the field. This probably means that the field can be changed to a local variable.

翻譯  單數的域:域變量只在一個方法中被使用並且第一次使用時對這個域賦值。這種域可以改寫爲本地變量。

public class Foo {

    private int x;  //Why bother saving this?

    public void foo(int y) {

     x = y + 5;

     return x;

    }

}

·  ReturnEmptyArrayRatherThanNull: For any method that returns an array, it's a better behavior to return an empty array rather than a null reference.

翻譯  返回空的數組而不要返回null:對於任何返回數組的方法,返回一個空的數組是一個比返回null引用更好的做法。

·  AbstractClassWithoutAnyMethod: If the abstract class does not provides any methods, it may be just a data container that is not to be instantiated. In this case, it's probably better to use a private or a protected constructor in order to prevent instantiation than make the class misleadingly abstract.

翻譯  沒有任何方法的抽象類:如果抽象類沒有提供任何的方法,它可能只是一個不可被實例化的數據容器,在這種狀況下,更好的方法是使用私有的或受保護的構造器以阻止實例化可以讓類避免帶有欺騙性的抽象。

·  TooFewBranchesForASwitchStatement: Switch are designed complex branches, and allow branches to share treatment. Using a switch for only a few branches is ill advised, as switches are not as easy to understand as if. In this case, it's most likely is a good idea to use a if statement instead, at least to increase code readability.

翻譯  switch表達式帶有太少的分支:switch表達式是被設計爲處理複雜分支的,並且允許分支共享處理邏輯。對於較少分支的情況使用switch是不明智的,因爲這樣代碼不易理解。因此,更好的主意是使用if表達式來代替,這樣至少可以增加代碼可讀性。


原文出處:http://blog.csdn.net/jack0511/article/details/5344309

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