现在的位置: 首页 > 综合 > 正文

PMD规则之Design Rules

2013年10月03日 ⁄ 综合 ⁄ 共 5872字 ⁄ 字号 评论关闭

·  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

抱歉!评论已关闭.