【问题标题】:Relying on default field initialisation - is bad programming style? [closed]依赖默认字段初始化 - 编程风格不好? [关闭]
【发布时间】:2020-02-15 13:28:51
【问题描述】:

我获得了官方 oracle 文档的链接:https://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html

在哪里说:

默认值

并不总是需要赋值 字段被声明。已声明但未初始化的字段将 由编译器设置为合理的默认值。通常来说,一般来说, 此默认值将为零或空,具体取决于数据类型。依靠 然而,在这样的默认值上,通常被认为是不好的 编程风格。

我想强调这部分:

然而,依赖这样的默认值通常被认为是糟糕的编程风格。

但是,天哪,我想说,这是语言规范的基本部分,知道实例变量具有默认值。如果它甚至在 Java SE 库源代码中被广泛使用,为什么这是一个糟糕的编程实践

【问题讨论】:

  • 嗯。我从来不知道那个声明在那里。我实际上认为依赖它们是一种很好的做法。 private int count = 0; 是什么都不做的代码,什么也不做的代码是混乱的。这就像从 java.lang 中导入类,或者用extends Object 声明一个类。
  • ... 或在接口中有public abstract 方法。
  • 公开摘要有什么问题?
  • 拼图的一部分可能来自 C++。它是一种流行的语言,它对默认初始化与零初始化的处理是错误的持续来源。在 C++ 中,除了最特殊的情况外,在所有情况下都依赖默认值是一个直接的坏主意。这可能在文化上已经渗入了 Java。
  • @JohnKeates - 我的 Java 有点生疏了,但是接口中的 private 方法没有意义,并且隐含了 abstract

标签: java default-value instance-variables


【解决方案1】:

简单:依赖默认值不会传达意图。

您真的希望该字段以 0 开头,还是您忘记分配一个值?!

当然,空引用是您遇到空指针异常所需的两件事的一半。

最后,使用默认值意味着您有非最终字段。尽可能避免。

唯一的反驳论点是:为什么要写下你不必写的东西?但我认为列出的缺点表明,明确地将 0 分配给字段比将其留给编译器要好。

【讨论】:

  • 即回复:不传达意图 - 如果“维护者曼尼”正在查看您的代码并且不知道特定数据类型的默认值是什么。他假设当它真的为 NULL 时它是 0,这就是 === 检查的整个错误(或者在 java 中对 value&type 进行的任何等效相等检查,equals()?)。几个小时的搜索(对于没有经验的程序员)可能是如此简单的结果。附:试图扮演魔鬼的拥护者。我说整天使用默认值(即使我从不这样做)并让更聪明的人(或至少更关注细节)来维护你的代码。
  • @TCoper 当维护者曼尼对 Java 知之甚少时,他就没有必要接触现实世界的 Java 代码了。但我同意基本概念。这让新手更难。
【解决方案2】:

为什么这是一个糟糕的编程习惯

这个想法是,如果您依赖默认值,那么阅读代码的任何人都不会立即明白您是否故意将其保留为默认值,或者您只是忘记分配它。

...如果它甚至在 Java SE 库源代码中也被广泛使用??

Java 源代码并不是您真正应该依赖的示例性编码实践示例。违反此类规则的情况有很多(有时是故意为了较小的性能改进,有时是意外或因为多年来公认的风格发生了变化。)

【讨论】:

  • 这可能是对的,虽然我不同意。
  • @VGR 尽管我倾向于同意依赖默认值是次优的说法,但出于这个原因,我小心翼翼地以中立的方式表达它。代码质量是主观的,我很清楚这绝不是普遍持有的观点。
【解决方案3】:

引用的文字是:

“然而,依赖这样的默认值通常被认为是糟糕的编程风格。”

玩世不恭:“通常认为”通常是一种说法,即作者没有试图为所发表的陈述找到权威来源。

在这种情况下,断言显然是有问题的。证据:5 份 Java 风格指南样本中有 5 份没有说明您是否应该或应该依赖默认值:

(注意,我的抽样方法是查看前 5 个不同的 Google 搜索命中的“java style guide”。然后我在每个文档中搜索“default”。这不是一个彻底的分析,但它用来说明我的观点。)


好的。那么它真的有助于 Java 代码的可读性吗?

这是有争议的。

一方面,没有了解默认初始化的新手 Java 程序员可能会对零或空值的来源感到困惑。但是,如果他们费心寻找显式初始化并发现没有,那应该足以让他们阅读教程或书籍来了解默认初始化。 (你会希望的!)

另一方面,我们通常不期望 Java 新手程序员维护生产代码库。对于有经验的 Java 程序员来说,冗余初始化不会提高可读性。它(充其量)是噪音。

在我看来,通过字段的冗余初始化实现的唯一一件事就是向您的代码的未来读者发出信号,表明您考虑过初始值。 (正如@GhostCat 所说,默认初始化不会传达意图。)

但相反,如果我是那个读者,我不一定会相信代码作者的想法。所以这个“信号”的价值也值得商榷。


可靠性怎么样?

在 Java 中没有区别。 JLS 指定默认初始化确实发生在字段中。相反,对于局部变量,尝试使用尚未明确初始化的变量是编译错误。

简而言之,未显式初始化的变量的运行时行为是完全可以预测的。

相比之下,在 C 或 C++ 等语言中,变量可能未初始化,其行为未指定,并可能导致崩溃以及不同平台上的行为差异。在这里总是显式初始化变量的情况要强得多。


性能怎么样?

应该没什么区别。 JIT 编译器应该能够将冗余初始化和默认初始化视为相同。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-10-18
    • 1970-01-01
    • 2019-10-04
    • 1970-01-01
    • 1970-01-01
    • 2015-07-08
    • 2020-01-18
    • 1970-01-01
    相关资源
    最近更新 更多