首页 文章

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

提问于
浏览
33

DataflowAnomalyAnalysis:找到变量'变量'的'DD'异常(行'n1' - 'n2') . DataflowAnomalyAnalysis:找到变量'变量'的'DU'-anomaly(行'n1' - 'n2') .

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

NullAssignment:将Object指定为null是代码气味 . 考虑重构 .

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

MethodArgumentCouldBeFinal:参数'param'未分配,可以声明为final LocalVariableCouldBeFinal:局部变量'variable'可以声明为final

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

LooseCoupling:避免使用像'LinkedList'这样的实现类型;改为使用界面

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

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

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

AvoidUsingShortType:不要使用短类型

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

6 回答

  • 1

    块级同步与方法级同步相比有哪些优势?同步一个方法就像做一个synchronize(getClass())块,并阻塞所有类 .

    也许你不想那样

  • 33

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

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

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

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

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

    您能想到为什么特别需要LinkedList的原因吗?

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

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

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

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

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

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

  • 0

    DataflowAnomalyAnalysis:找到变量'变量'的'DD'异常(行'n1' - 'n2') . DataflowAnomalyAnalysis:找到变量'变量'的'DU'-anomaly(行'n1' - 'n2') .

    不知道 .

    NullAssignment:将Object指定为null是代码气味 . 考虑重构 . 如果对象是本地对象(不在方法之外使用),则不会将对象设置为null辅助垃圾收集吗?或者这是一个神话?

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

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

    MethodArgumentCouldBeFinal:参数'param'未分配,可以声明为final LocalVariableCouldBeFinal:局部变量'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();
         }
      }
    

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

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

    它会让你花一点时间发现在中间的某个点,somone更改引用,并且你正在使用其他对象 .

    使用 final 帮助来防止这种事情 .

    LooseCoupling:避免使用'LinkedList'之类的实现类型;改为使用界面如果我知道我特别需要一个LinkedList,为什么我不会用一个来明确表达未来开发人员的意图?返回有意义的类路径中最高的类是一回事,但为什么我不会声明我的变量是最严格的呢?

    在这种情况下没有区别 . 我认为既然你没有使用 LinkedList 具体功能,那么建议是公平的 .

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

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

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

    AvoidSynchronizedAtMethodLevel:使用块级而不是方法级同步块级同步与方法级同步相比有哪些优势?

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

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

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

    我从来没有听说过这个,我同意你的观点:)我从来没有用过短片 .

    我的猜测是,通过不使用它,你将帮助你自己无缝升级到 int .

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

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

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

  • 0

    AvoidUsingShortType:不要使用短类型

    • 列出项目

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

    • 一个简短的数学运算,在Integer族中除了另一个short之外的任何东西都需要将运行符符号扩展转换为更大的大小 . 针对浮点运算需要符号扩展和对IEEE-754的非平凡转换 .

    • 可以't find proof, but with a 32 bit or 64 bit register, you'不再在字节码级别保存'processor instructions' . 就处理器寄存器而言,你是一个停车位 .

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

    • 我同意忽略此pmd警告的设计方面,只需用'short'与所产生的性能转换来准确描述您的对象 .

    • 在我看来,在大多数机器上发生的性能命中都是微不足道的 . 忽略错误 .

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

    • null 分配给局部变量以便"assist"垃圾收集器是一个神话 . PMD让你知道这只是适得其反的混乱 .

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

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

    • 我无法想到调用者需要 LinkedList 的许多情况,因为它没有被某些接口声明 . 如果客户端依赖于该API,则可通过正确的接口使用它 .

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

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

  • 3

    只是关于 final 问题的注释 .

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

    请考虑以下几点:

    • 任何带有 final 的变量都可以立即归入"will not change value while watching" .
      _999_暗示它意味着如果所有不会改变的变量都标记为final,那么未标记为final的变量实际上会改变 .

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

相关问题