36

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

DataflowAnomalyAnalysis:发现变量“变量”的“DU”异常(行“n1”-“n2”)。

DD 和 DU 听起来很熟悉……我想说的是与最弱的前后条件相关的测试和分析,但我不记得具体内容了。

NullAssignment:将 Object 分配给 null 是一种代码味道。考虑重构。

如果对象是本地对象(不在方法之外使用),是否不会设置对象来null协助垃圾收集?或者这是一个神话?

MethodArgumentCouldBeFinal:未分配参数“param”,可以声明为 final

LocalVariableCouldBeFinal:局部变量“变量”可以声明为最终变量

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

LooseCoupling:避免使用“LinkedList”等实现类型;改用界面

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

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

块级同步比方法级同步有什么优势?

AvoidUsingShortType:不要使用短类型

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

4

6 回答 6

35
  • DD 和 DU 异常(如果我没记错的话——我使用 FindBugs 并且消息有点不同)是指将一个值分配给一个永远不会被读取的局部变量,通常是因为它在被读取之前被重新分配了另一个值。一个典型的情况是null在声明某个变量时对其进行初始化。在需要之前不要声明变量。

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

  • 在局部变量上指定 final 对优化器来说应该非常有用,但我没有任何当前 JIT 利用这个提示的具体示例。我发现它在推理我自己的代码的正确性时很有用。

  • 根据……来指定接口,接口是一种很好的设计实践。您可以轻松更改集合的实现而不影响调用者。这就是接口的全部意义所在。

  • 我想不出调用者需要a的许多情况LinkedList,因为它不公开任何未由某个接口声明的 API。如果客户端依赖该 API,则可以通过正确的接口使用它。

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

  • 类型的操作数在任何操作中都会short被提升。int此规则让您知道此促销正在发生,您不妨使用int. 但是,使用该short类型可以节省内存,所以如果它是实例成员,我可能会忽略该规则。

于 2009-10-23T19:34:43.213 回答
3

只是关于这个final问题的注释。

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

请考虑以下几点:

  • 任何带有 a 的变量final都可以立即归类为“观看时不会改变值”。
  • 暗示这意味着如果所有不会改变的变量都用final标记,那么没有用final标记的变量实际上会改变。

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

于 2010-12-15T13:32:11.130 回答
3

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

DataflowAnomalyAnalysis:发现变量“变量”的“DU”异常(行“n1”-“n2”)。

不知道。

NullAssignment:将 Object 分配给 null 是一种代码味道。考虑重构。

如果对象是本地对象(不在方法之外使用),是否不会设置对象来null协助垃圾收集?或者这是一个神话?

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

由于它会使经验较少的开发人员变得缺乏经验,所以关于它的空赋值可能被认为是代码异味。

MethodArgumentCouldBeFinal:未分配参数“param”,可以声明为 final

LocalVariableCouldBeFinal:局部变量“变量”可以声明为最终变量

使用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方法(根据您的发现)

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

使用final帮助来防止这种事情发生。

LooseCoupling:避免使用“LinkedList”等实现类型;改用界面

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

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

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

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

此外,还可以帮助经验不足的开发人员养成良好的习惯。[我不是说你是其中之一,但分析仪不认识你;)]

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

块级同步比方法级同步有什么优势?

同步部分越小越好。而已。

此外,如果您在方法级别进行同步,您将阻塞整个对象。当您在块级别同步时,您只需同步该特定部分,在某些情况下这就是您需要的。

AvoidUsingShortType:不要使用短类型

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

我从来没有听说过这个,我同意你的观点:)我从来没有使用过short。

我的猜测是,如果不使用它,您将帮助自己 int无缝升级。

代码异味更注重代码质量而不是性能优化。因此,建议是针对经验不足的程序员并避免陷阱,而不是提高程序速度。

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

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

于 2009-10-23T19:40:02.500 回答
1

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

它所做的唯一一件事就是让对象在方法结束之前被 GCd 成为可能,而这很少需要。

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

它使代码更加清晰,因为您不必担心在分析代码时会在某处更改值。更常见的是,一旦设置了变量,您就不需要或不想更改变量的值。

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

你能想到为什么你会特别需要 LinkedList 吗?

返回有意义的类路径中最高的类是一回事,但是为什么我不将变量声明为最严格的呢?

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

块级同步比方法级同步有什么优势?

最大的一个是它使您能够使用专用的监视器对象,以便只有那些需要互斥的关键部分,而不是使用相同的监视器。

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

因为小于 int 的类型在所有计算中都会自动提升为 int 并且您必须向下转换才能为它们分配任何东西。这会导致代码混乱和混乱(尤其是在涉及自动装箱时)。

于 2009-10-23T20:13:03.353 回答
0

AvoidUsingShortType:不要使用短类型

  • 项目清单

    short 是 16 位,java 中的 2 的恭维

  • 对 Integer 系列中的任何内容进行简短的数学运算,需要将运行时符号扩展转换为更大的大小。针对浮点操作需要符号扩展和到 IEEE-754 的重要转换。

  • 找不到证据,但是使用 32 位或 64 位寄存器,您不再在字节码级别节省“处理器指令”。就处理器寄存器而言,您将一辆紧凑型汽车停在半挂车的停车位。

  • 如果您正在字节码级别优化您的项目,哇。哇。;P

  • 我同意忽略此 pmd 警告的设计方面,只需权衡准确地用“短”描述您的对象与产生的性能转换。

  • 在我看来,在大多数机器上产生的性能损失是微不足道的。忽略错误。

于 2009-10-23T20:11:02.343 回答
0

块级同步比方法级同步有什么优势?同步一个方法就像做一个synchronize(getClass())块,并块所有的类。

也许你不想要那个

于 2010-03-18T18:45:42.353 回答