【问题标题】:Avoid uninitialized non final member class/ class variable避免未初始化的非最终成员类/类变量
【发布时间】:2019-03-19 12:18:57
【问题描述】:

我发现 Java 编译器和/或声纳警告没有完全涵盖防止忘记初始化对象,我正在使用最新的 Eclipse 和最新的声纳插件。

我缺少关于未初始化的错误/警告,例如 Map(也可以是 String

在示例 Class Variable mapStaticMember Variable map 中,它们都是私有的而不是最终的,可以在没有初始化的情况下声明,也没有任何关于 NullPointerException 的错误/警告。

虽然对于局部变量 mapVar 我得到编译错误 Compile The local variable mapVar may not have been initialized

显然是局部变量are not assign with default value,但为什么编译器/声纳没有警告 NullPointerException?

局部变量略有不同;编译器永远不会为未初始化的局部变量分配默认值。

private static Map<String, String> mapStatic; // Missing compile/warning
private Map<String, String> map; // Missing compile/warning
public void  put() {
    map.put("x", "1"); // NullPointerException
    //Map<String, String> mapVar;
    //mapVar.put("x", "1"); // Compile The local variable mapVar may not have been initialized
}
static {
    mapStatic.put("x", "1"); // NullPointerException        
}

另外,如果我添加final,我会得到编译错误Compile The local variable map may not have been initialized

我发现an answer不会在编译时出现,如何提前避免或发现这个问题?

未能初始化一个值是程序员的逻辑错误,应该尽快发现。 Java 在编译时为本地人执行此操作,但仅在运行时(或根本不)为字段执行此操作。

【问题讨论】:

  • 您想要什么样的警告?您是否希望编译器验证每个方法以查看其中是否存在实例化,您是否希望编译器查找使用您的类的每个类,无论该方法是否在使用该变量的任何其他方法之前被调用.
  • @Stultuske 好点,但它仍然是私人的,没有公共设置器,我想避免/发现此类问题
  • 编译器错误不会取代对体面的单元测试的需要,它可以很容易地发现这种类型的错误。
  • 我会尽可能将 Maps 和 Collections 设为最终版本,并在声明它们的行进行初始化。执行其中任何一项都可以防止 NPE。
  • jonskeet's answer to a related question 花了一点时间讨论为什么编译器不检查它。

标签: java compiler-errors initialization sonarqube sonarlint


【解决方案1】:

您似乎正在寻找的行为更有可能产生不必要的警告而不是帮助设计。

类级字段获得 JVM 分配的默认值是设计使然,出于多种原因,这是可以的,包括:

  • 字段的值可能要等到对象构造完成后才能知道。这是典型的,因为许多字段值只能在 setters 中设置。
  • 当前类本身可能不知道值是什么。在这种情况下,设置值的责任在类之外,因此警告只会令人烦恼。
  • 如果该字段根本不会在当前类中使用怎么办?

这是开发人员负责的领域。只有你知道执行的顺序,只有你知道代码依赖什么数据,也只有你有责任对代码进行测试,确保它没有 bug。

【讨论】:

  • 如果我在课堂上不使用(删除put)它,我会收到警告The value of the field map/mapStatic is not used
  • @user7294900 是的,但那是另一回事。初始化警告需要知道调用的顺序(如果不在本地范围内,这在编译时是不可能弄清楚的)。仅给定当前类中的访问修饰符和引用,就可以确定该字段可能是无用的,这证明了未使用的警告是正确的。
猜你喜欢
  • 2021-06-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-13
  • 1970-01-01
  • 2011-11-02
相关资源
最近更新 更多