接口常量有什么用?

新手上路,请多包涵

我正在学习 Java,刚刚发现接口可以有字段,这些字段是 public static 和 final 的。到目前为止,我还没有看到任何这样的例子。这些接口常量有哪些用例?我可以在 Java 标准库中看到一些用例吗?

原文由 unj2 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.1k
2 个回答

将静态成员放入接口(并实现该接口)是 一种不好的做法,它甚至有一个名称, _常量接口反模式_,请参阅 Effective Java ,第 17 项:

常量接口模式是对接口的不良使用。一个类在内部使用一些常量是一个实现细节。实现常量接口会导致此实现细节泄漏到类的导出 API 中。对于类的用户来说,类实现常量接口并不重要。事实上,这甚至会让他们感到困惑。更糟糕的是,它代表了一种承诺:如果在未来的版本中类被修改以使其不再需要使用常量,它仍然必须实现接口以确保二进制兼容性。如果非最终类实现常量接口,则其所有子类的名称空间都将被接口中的常量污染。

java平台库中有几个常量接口,比如 java.io.ObjectStreamConstants 。这些接口应该被视为异常,不应被仿效。

为了避免常量接口的一些陷阱(因为你不能阻止人们实现它),应该首选具有私有构造函数的适当类(从 维基百科 借来的例子):

 public final class Constants {

    private Constants() {
        // restrict instantiation
    }

    public static final double PI = 3.14159;
    public static final double PLANCK_CONSTANT = 6.62606896e-34;
}

要访问常量而不必完全限定它们(即不必在它们前面加上类名),请使用 静态导入(自 Java 5 起):

 import static Constants.PLANCK_CONSTANT;
import static Constants.PI;

public class Calculations {

    public double getReducedPlanckConstant() {
        return PLANCK_CONSTANT / (2 * PI);
    }
}

原文由 Pascal Thivent 发布,翻译遵循 CC BY-SA 3.0 许可协议

“ _常量接口模式是对接口的不良使用_”

无论是谁编造了这个假设,无论他/她可能是一位大师,都是基于继续有效地养成不良习惯和做法的需要而编造的。该假设是基于提升不良软件设计习惯的有效性。

我在这里写了一个反驳该假设的回应: What is the best way to implement constants in Java? 解释这个假设的毫无根据。

10 年来,这个问题一直悬而未决,直到我发布了证明这一假设不合理的理由后 2 小时内它才被关闭,从而暴露了那些坚持这一错误假设的人不愿意进行辩论的意愿。

这些是我反对假设的观点

  • 持有这个假设的基础是需要方法和限制性规则来应对不良软件习惯和方法的影响。

  • “ _持续的界面模式是对界面的不良使用_”这一观点的支持者除了需要应对那些不良习惯和做法的影响外,无法提供任何其他原因。

  • 解决根本问题。

  • 然后,为什么不充分利用和利用 Java 语言结构的每一种语言特性,以方便您使用。无需夹克。为什么要发明规则来阻止你无效的生活方式来歧视和指责更有效的生活方式?

根本问题

是信息组织。在为流程设计或补充解决方案之前,应首先了解调解流程的信息以及该信息的行为以及所谓的业务规则。这种信息组织方式在几十年前被称为数据规范化。

然后只有解决方案的工程才有可能,因为将解决方案组件的粒度和模块化与信息组件的粒度和模块化对齐是最佳策略。

组织信息有两三个重大障碍。

  1. 缺乏对数据模型“规范化”需求的认识。

  2. EF Codd 关于数据规范化的陈述是有缺陷的、有缺陷的和模棱两可的。

  3. 伪装成敏捷工程的最新时尚是一种错误的观念,即人们不应该提前计划和调节模块的组织,因为您可以随时重构。以不受未来发现阻碍的方式进行重构和持续变化作为借口。过程信息行为的基本发现是通过使用会计技巧来延迟利润和资产化,因此现在认为不需要基本知识及其处理。

使用接口常量是一种很好的做法。

不要仅仅因为喜欢即兴即跑的编程习惯就制定规则或发布任何反对它的法令。

不要以有些人不知道如何使用枪支或容易滥用枪支为由禁止拥有枪支。

如果您制定的规则适用于无法专业编码的编程新手,并且您将自己算作他们中的一员,那么请这样说 - 不要声明您的法特瓦适用于正确规范化的数据模型。

一个愚蠢的推理 - 接口不是 Java 语言的创始人打算以这种方式使用的吗?

我不在乎开国元勋对美国宪法的初衷是什么。我不关心不成文的未编纂的意图。我只关心成文宪法中以文字形式编纂的内容,以及我如何利用它们来使社会有效运作。

我只关心 Java 语言/平台规范允许我做什么,我打算充分利用它们,为我提供一种高效表达我的软件解决方案的媒介。不需要夹克。

使用枚举常量实际上是一种可怕的做法。

它需要编写额外的代码来将参数映射到值。事实上,Java 的创始人没有提供参数值映射,而您没有编写映射代码来演示枚举常量,这与 Java 语言的无意使用一样。

特别是因为不鼓励您规范化和组件化您的参数,所以会有一种错误的印象,即混合到 Enum 包中的参数属于同一维度。

常量是 API 契约

不要忘记这一点。如果您设计并规范化了数据模型,并且它们包含常量,那么这些常量就是契约。如果您没有规范化您的数据模型,那么您应该遵守关于如何练习限制性编码以应对该坏习惯的法特瓦。

因此,接口是实现常量契约的完美方式。

一个奇怪的假设——如果接口不小心被实现了怎么办。

是的。任何人都可能不经意地实现任何接口。没有什么能阻止这种粗心的程序员。

设计和规范化您的数据模型以防止泄漏

不要制定限制性法令来保护可能导致未约定/杂散参数泄漏到 API 中的假定不良做法。解决根本问题,而不是将责任归咎于接口常量。

不使用 IDE 是不好的做法

一个正常运作且高效的程序员不会在那里证明她可以在水下呆多久,她可以在酷热或潮湿的雷暴中走多远。她要使用高效的工具,例如汽车或公共汽车,或者至少是自行车,每天上班 10 英里。

不要仅仅因为你对无 IDE 编程有一种深奥的禁欲主义痴迷而对其他程序员施加限制。

一些框架旨在帮助程序员有效地继续养成坏习惯。

OSGI就是这样一个框架。反对接口常量的法令也是如此。

因此,结论性答案……

接口常量是一种有效且高效的方式,可以将精心设计和规范化的数据模型组件放入合同中。

嵌套在类文件中的适当命名的私有接口中的接口常量也是将所有私有常量分组而不是将它们分散在整个文件中的好习惯。

原文由 Blessed Geek 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题