java - 简单、普遍、基于代码分析器的 Java 问题

标签 java static-analysis findbugs pmd

关闭。这个问题需要更多focused .它目前不接受答案。












想改善这个问题吗?更新问题,使其仅关注一个问题 editing this post .

6年前关闭。




Improve this question




好的,在用 PMD 查看了一些代码之后和 FindBugs代码分析器,我能够对审查的代码进行重大更改。但是,有些事情我不知道如何解决。我将在下面迭代它们,并且(为了更好的引用)我会给每个问题一个数字。随意回答任何/所有。谢谢你的耐心。

1.即使我已经删除了一些规则,在重新评估代码后,相关的警告仍然存在。知道为什么吗?

2. 请看声明:

    private Combo comboAdress;

    private ProgressBar pBar;

以及 getter 和 setter 对对象的引用:
    private final Combo getComboAdress() {
  return this.comboAdress;
 }

 private final void setComboAdress(final Combo comboAdress) {
  this.comboAdress = comboAdress;
 }

 private final ProgressBar getpBar() {
  return this.pBar;
 }

 private final void setpBar(final ProgressBar pBar) {
   this.pBar = pBar;
 }

现在,我想知道为什么第一个声明没有给我任何关于 PMD 的警告,而第二个给我以下警告:
Found non-transient, non-static member. Please mark as transient or provide accessors.

有关该警告的更多详细信息 here .

3. 这是另一个警告,也是由 PMD 给出的:
    A method should have only one exit point, and that should be the last statement in the method

有关该警告的更多详细信息 here .

现在,我同意这一点,但如果我写这样的东西怎么办:
public void actionPerformedOnModifyComboLocations() {
    if (getMainTree().isFocusControl()) {
        return;
    }
    ....//do stuffs, based on the initial test
}

我倾向于同意该规则,但如果代码的性能表明存在多个退出点,我该怎么办?

4. PMD 给了我这个:
Found 'DD'-anomaly for variable 'start_page' (lines '319'-'322').

当我声明如下内容时:
String start_page = null;

如果我删除对 null 的赋值,我会删除此信息(警告级别为信息),但是..我从 IDE 收到错误,说变量可能未初始化,在代码稍后的某个时间点。所以,我有点坚持这一点。抑制警告是你能做的最好的事情吗?

5. PMD 警告:
Assigning an Object to null is a code smell.  Consider refactoring.

这是 GUI 组件的单调使用情况或返回复杂对象的方法的情况。在 catch() 部分将结果分配给 null 是因为需要避免返回不完整/不一致的对象。是的,应该使用 NullObject,但在某些情况下我不想这样做。那么我应该抑制那个警告吗?

6. FindBugs 警告 #1:
Write to static field MyClass.instance from instance method MyClass.handleEvent(Event)

在方法中
@Override
public void handleEvent(Event e) {
    switch (e.type) {
        case SWT.Dispose: {
            if (e.widget == getComposite()) {
                MyClass.instance = null;
            }
       break;
         }
    }
}

静态变量
private static MyClass instance = null;

该变量允许我测试表单是否已经创建并且是否可见,并且在某些情况下我需要强制重新创建表单。我在这里看不到其他选择。任何见解? (MyClass 实现了 Listener,因此重写了 handleEvent() 方法)。

7. FindBugs 警告 #2:
Class MyClass2 has a circular dependency with other classes

此警告是基于其他类的简单导入而显示的。我是否需要重构这些导入以使此警告消失?还是问题依赖于 MyClass2?

好的,现在说的够多了……期待更新,基于更多的发现和/或你的答案。谢谢。

最佳答案

以下是我对您的一些问题的回答:

问题号 2 :

我认为您没有正确地将属性大写。这些方法应该被称为 getPBar 和 setPBar。

String pBar;

void setPBar(String str) {...}
String getPBar() { return pBar};

JavaBeans 规范指出:

For readable properties there will be a getter method to read the property value. For writable properties there will be a setter method to allow the property value to be updated. [...] Constructs a PropertyDescriptor for a property that follows the standard Java convention by having getFoo and setFoo accessor methods. Thus if the argument name is "fred", it will assume that the reader method is "getFred" and the writer method is "setFred". Note that the property name should start with a lower case character, which will be capitalized in the method names.



问题号 3 :

我同意您使用的软件的建议。为了可读性,只有一个导出点更好。为了效率,使用'return;'可能会更好。我的猜测是编译器足够聪明,可以始终选择有效的替代方案,我敢打赌,这两种情况下的字节码都是相同的。

更多经验信息

我做了一些测试,发现我使用的 java 编译器(Mac OS X 10.4 上的 javac 1.5.0_19)没有应用我期望的优化。

我使用以下类进行测试:
public abstract class Test{

  public int singleReturn(){   
     int ret = 0;
     if (cond1())
         ret = 1;
     else if (cond2())
         ret = 2;
     else if (cond3())
         ret = 3;

    return ret;
  }

  public int multReturn(){
    if (cond1()) return 1;
    else if (cond2()) return 2;
    else if (cond3()) return 3;
    else return 0;
  }

  protected abstract boolean cond1();
  protected abstract boolean cond2();
  protected abstract boolean cond3();
}

然后,我分析了字节码,发现对于multReturn()有几个'ireturn'语句,而对于singleReturn()只有一个。此外,singleReturn() 的字节码还包括几个 goto 到 return 语句。

我使用非常简单的 cond1、cond2 和 cond3 实现测试了这两种方法。我确保这三个条件同样可证明。我发现了 3% 到 6% 的持续时间差异,赞成multReturn() .在这种情况下,由于操作非常简单,倍数返回的影响是非常明显的。

然后我使用更复杂的 cond1、cond2 和 cond3 实现测试了这两种方法,以便使不同返回的影响不那么明显。我被结果震惊了!现在 multReturn() 始终是 较慢 比 singleReturn() (在 2% 到 3% 之间)。我不知道是什么导致了这种差异,因为其余的代码应该是相同的。

我认为这些意想不到的结果是由JVM的JIT编译器造成的。

无论如何,我坚持我最初的直觉:编译器(或 JIT)可以优化这些东西,这让开发人员可以专注于编写易于阅读和维护的代码。

问题号 6 :

您可以从实例方法调用类方法,并保留该静态方法更改类变量。

然后,您的代码类似于以下内容:
public static void clearInstance() {
    instance = null;
}

@Override
public void handleEvent(Event e) {
    switch (e.type) {
        case SWT.Dispose: {
            if (e.widget == getComposite()) {
                MyClass.clearInstance();
            }
       break;
         }
    }
}

这会导致您在 5 中描述的警告,但必须有一些妥协,在这种情况下,它只是一种气味,而不是错误。

问题号 7 :

这只是一个可能的问题的味道。它不一定是坏的或错误的,您不能仅通过使用此工具来确定。

如果你有一个真正的问题,比如构造函数之间的依赖关系,测试应该显示它。

一个不同但相关的问题是 jar 之间的循环依赖:虽然可以编译具有循环依赖的类,但由于类加载器的工作方式,无法在 JVM 中处理 jar 之间的循环依赖。

关于java - 简单、普遍、基于代码分析器的 Java 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1582512/

相关文章:

c - 为什么 Ideone.com C 编译器不捕获不匹配的指针类型?

java - 可能会抛出 "NullPointerException"; "context"在这里可以为空

javascript - 如何遍历spidermonkey生成的AST(Javascript文件)

plugins - 如何在 gradle findbugs 插件中将报告的错误打印到控制台?

java - 显示标签库出现错误 "You must specify one of the following: size"

java - 使用反射的 ToStringBuilder、HashCodeBuilder、EqualsBuilder 有多慢

Android 应用程序的 Java 编程无法加载

java - 在 Eclipse 中查看实时堆

android - 如何为子项目或应用程序级别的 build.gradle 指定 gradle 版本

java - NP_NULL_PARAM_DEREF_NONVIRTUAL : i donot understand or false positive