这些PMD规则的原因是什么?

时间:2009-10-23 19:22:52

标签: java pmd

  

DataflowAnomalyAnalysis:发现   变量'变量'的'DD'异常   (行'n1' - 'n2')。

     

DataflowAnomalyAnalysis:发现   变量'变量'的'DU'-anomaly   (行'n1' - 'n2')。

DD和DU听起来很熟悉...我想说的是关于最弱前后条件的测试和分析,但我不记得具体细节。

  

NullAssignment:将对象分配给   null是代码气味。考虑   重构。

如果对象是本地对象(在方法之外没有使用),是不是将对象设置为null辅助垃圾收集?或者这是一个神话?

  

MethodArgumentCouldBeFinal:参数   'param'未分配,可能是   宣布最终

     

LocalVariableCouldBeFinal:Local   可以声明变量'variable'   最终

使用final参数和变量有什​​么好处吗?

  

LooseCoupling:避免使用   实现类型如   “链表”;使用界面   代替

如果我知道我特别需要一个LinkedList,为什么我不会用一个来明确向未来的开发者明确表达我的意图?返回有意义的类路径中最高的类是一回事,但为什么我不会声明我的变量是最严格的呢?

  

AvoidSynchronizedAtMethodLevel:使用   块级而不是方法级   同步

块级同步与方法级同步相比有哪些优势?

  

AvoidUsingShortType:不要使用   短型

我的第一语言是C和C ++,但在Java世界中,为什么我不能使用最能描述我数据的类型呢?

6 个答案:

答案 0 :(得分:33)

  • DD和DU异常(如果我没记错的话 - 我使用FindBugs并且消息有点不同)指的是为永远不会读取的局部变量赋值,通常是因为它之前被重新分配了另一个值正在阅读一个典型的例子是在声明时用null初始化一些变量。 Don't declare the variable until it's needed.

  • null分配给局部变量以“协助”垃圾收集器是一个神话。 PMD让你知道这只是适得其反的混乱。

  • 在本地变量上指定final应该对优化器非常有用,但我没有任何利用此提示的当前JIT的具体示例。我发现它有助于推断我自己的代码的正确性。

  • 根据......好,接口指定接口是一个很好的设计实践。您可以轻松更改集合的实现,而不会影响调用者。这就是接口的全部内容。

  • 我无法想到调用者需要 LinkedList的许多情况,因为它不会暴露任何未被某些接口声明的API。如果客户端依赖于该API,则可以通过正确的界面获得它。

  • 块级同步允许关键部分更小,这允许尽可能多地同时完成工作。也许更重要的是,它允许使用由封闭对象私有控制的锁定对象。这样,您可以保证不会发生死锁。使用实例本身作为锁,任何人都可以错误地同步它,导致死锁。

  • 在任何操作中,short类型的操作数都会提升为int。此规则可让您知道此促销活动正在进行,您也可以使用int。但是,使用short类型可以节省内存,因此如果它是实例成员,我可能会忽略该规则。

答案 1 :(得分:3)

  

DataflowAnomalyAnalysis:发现   变量'变量'的'DD'异常   (行'n1' - 'n2')。

     

DataflowAnomalyAnalysis:发现   变量'变量'的'DU'-anomaly   (行'n1' - 'n2')。

不知道。

  

NullAssignment:将对象分配给   null是代码气味。考虑   重构。

     

如果对象是本地对象(在方法之外没有使用),是不是将对象设置为null辅助垃圾收集?或者这是一个神话?

方法返回后,本地方法中的对象被标记为垃圾回收。将它们设置为null将没有任何区别。

因为它会减少开发人员的经验,所以关于它的null赋值可能被视为代码气味。

  

MethodArgumentCouldBeFinal:参数   'param'未分配,可能是   宣布最终

     

LocalVariableCouldBeFinal:Local   可以声明变量'variable'   最终

     

使用final参数和变量有什​​么好处吗?

更清楚的是,在对象的生命周期中,值不会改变。

此外,如果有人试图分配值,编译器将在编译类型时阻止此编码错误。

考虑一下:

 public void businessRule( SomeImportantArgument important )  {
      if( important.xyz() ){
          doXyz();
      }
      // some fuzzy logic here
      important = new NotSoImportant();
      // add for/if's/while etc 

     if( important.abc() ){ // <-- bug
         burnTheHouse();
     }
  } 

假设你被指派解决一些不时烧毁房子的神秘虫子。

你知道参数使用的是什么,你不明白的是为什么如果条件不满足,则调用burnTHeHouse方法(根据你的发现)

您需要花一些时间才能发现在中间的某个位置, somone 更改了引用,并且您正在使用其他对象。

使用final帮助来阻止此类事情发生。

  

LooseCoupling:避免使用   实现类型如   “链表”;使用界面   代替

     

如果我知道我特别需要一个LinkedList,为什么我不会用一个来明确表达未来开发人员的意图?返回有意义的类路径中最高的类是一回事,但为什么我不能将我的变量声明为最严格的意义呢?

在这种情况下没有区别。我认为,由于您没有使用LinkedList特定功能,因此建议是公平的。

今天,LinkedList可能有意义,但通过使用界面,你可以帮助你自己(或其他人)轻松改变它。

对于小型个人项目,这可能根本没有意义,但由于您已经使用了分析仪,我猜您已经关注代码质量了。

此外,帮助经验不足的开发人员创造良好的习惯。 [我不是说你是一个,但分析仪不认识你;)

  

AvoidSynchronizedAtMethodLevel:使用   块级而不是方法级   同步

     

块级同步与方法级同步相比有哪些优势?

同步部分越小越好。就是这样。

此外,如果在方法级别进行同步,则会阻止整个对象。在块级别进行同步时,只需在某些情况下同步该特定部分即可。

  

AvoidUsingShortType:不要使用   短型

     

我的第一语言是C和C ++,但在Java世界中,为什么我不能使用最能描述我数据的类型?

我从来没有听说过这个,我同意你的看法:)我从来没用过短片。

我的猜测是,如果不使用它,你就会帮助自己无缝升级到int

代码味道比性能优化更倾向于代码质量。因此,为经验不足的程序员提供建议并避免陷阱,而不是提高程序速度。

这样,在尝试更改代码以适应更好的设计时,可以节省大量时间和挫折。

如果建议没有意义,只要忽略它们,记住,你是负责的开发人员,而工具只是一个工具。如果出现问题,你不能责怪这个工具,对吧?

答案 2 :(得分:3)

关于final问题的说明。

在变量上加上“final”会导致它只能分配一次。这并不一定意味着它更容易编写,但它肯定意味着为未来的维护者更容易。

请考虑以下几点:

  • 任何带有final的变量都可以立即归类为“在观看时不会改变价值”。
  • 暗示它意味着如果所有不会改变的变量都标记为final,那么未标记为final的变量实际上会发生变化。

这意味着你可以在阅读定义部分时看到哪些变量需要注意,因为它们可能会在代码中改变值,并且维护者可以更好地花费他/她的努力,因为代码更具可读性。 / p>

答案 3 :(得分:1)

  

不会将对象设置为null   协助垃圾收集,如果   object是一个本地对象(未使用   方法之外)?或者那是一个   神话?

它唯一能做的就是在方法结束之前使对象成为GCd,这很少是必要的。

  

使用最终参数和变量有什​​么好处吗?

它使代码更清晰,因为您在分析代码时不必担心值被更改。更常见的是,无论如何,您都不需要或想要更改变量的值。

  

如果我知道我特别需要一个   LinkedList,为什么我不会使用一个   明确表达我的意图   未来开发商?

你能想出为什么你特别需要一个 链表?

  

这是一回事   返回最高级别的班级   类路径有意义,但为什么   我不会声明我的变量   最严格意义上的?

我不太关心局部变量或字段,但如果你声明一个LinkedList类型的方法参数,我会追捕你并伤害你,因为它使我无法使用像Arrays.asList()Collections.emptyList()

  

块级同步与方法级同步相比有哪些优势?

最大的一点是,它允许您使用专用的监视器对象,以便只有那些关键部分是相互排斥的,而不是使用相同监视器的所有部分。

  

在Java世界中,我为什么不这样做   使用最能描述我的类型   数据?

因为小于int的类型会在所有计算中自动提升为int,并且必须向下转换为它们分配任何内容。这导致代码混乱和相当多的混乱(特别是涉及自动装箱时)。

答案 4 :(得分:0)

AvoidUsingShortType:不要使用短类型

  • 列出项目

    简短是16位,2是java的赞美

  • 一个简短的数学运算,在另一个short之外的整数族中的任何东西都需要将运行符符号扩展转换为更大的大小。针对浮点运算需要符号扩展和非平凡的IEEE-754转换。
  • 找不到证明,但是使用32位或64位寄存器,您不再在字节码级别保存“处理器指令”。就处理器注册而言,你正在一辆半挂车的停车位停放一辆小型车。
  • 如果您要在字节码级别优化项目,哇。哇。 ; P
  • 我同意忽略此pmd警告的设计方面,只需用“短”与产生的性能转换来准确描述您的对象。
  • 在我看来,在大多数机器上发生的性能命中都是微不足道的。忽略错误。

答案 5 :(得分:0)

  

块级有什么优势   同步已超过方法级别   同步?   同步方法就像执行synchronize(getClass())块一样,并阻止所有类。

也许你不想要那个