接口常量的用途是什么?

2022-08-31 07:36:19

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


答案 1

将静态成员放入接口(并实现该接口)是一种不好的做法,甚至还有一个名称,常量接口反模式,请参阅 Effective Java,Item 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);
    }
}

答案 2

"常量接口模式是接口的不良使用"

无论谁编造了这个假设,无论他/她多么像大师,都是基于需要继续有效地实施坏习惯和实践而编造的。该假说是基于促进不良软件设计习惯的有效性。

我在这里写了一个针对这个假设的反驳:在Java中实现常量的最佳方法是什么?解释了这个假设的无根据性。

10年来,这个问题一直悬而未决,直到在我发布我的理由使这个假设变得不合理之后的2小时内就结束了,从而暴露了那些坚持这个错误假设的人的辩论的UNWILLING性。

这些是我针对假设所表达的观点

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

  • 恒定的界面模式是对接口的不良使用”的观点的支持者无法提供任何理由,除了那些需要应对这些坏习惯和做法的影响而引起的原因。

  • 解决根本问题。

  • 然后,为什么不充分利用和利用Java语言结构的每种语言功能来方便自己。无需夹克。为什么要制定规则来阻止你无效的生活方式,以歧视和歧视更有效的生活方式?

根本问题

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

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

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

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

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

  3. 伪装成敏捷工程的最新时尚是一种被误导的观念,即人们不应该提前计划和调整模块的组织,因为你可以随心所欲地重构。重构和持续变化而不被未来的发现所阻碍,被用作借口。因此,通过使用会计技巧来延迟利润和资产化,对流程信息行为的基本发现是,因此现在不需要基本知识和它们的处理。

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

不要仅仅因为你喜欢你临时的即打即用编程习惯而制定规则或发布任何针对它的法特瓦。

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

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

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

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

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

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

它需要编写额外的代码来将参数映射到值。Java的创始人在没有编写映射代码的情况下没有提供参数值映射,这一事实表明Enum常量同样是Java语言的意外使用。

特别是因为不鼓励您对参数进行规范化和组件化,因此会有一种错误的印象,即混合到Enum包中的参数属于同一尺寸。

常量是 API 协定

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

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

一个奇怪的假设 - 如果接口无意中被实现怎么办。

是的。任何人都可能无意中实现任何接口。没有什么能阻挡这些无意的程序员。

针对泄漏设计和规范化数据模型

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

不使用 IDE 是一种不好的做法

一个正常运作和有效的程序员不能证明她可以在水下呆多久,在炎热或潮湿的雷暴中她能走多远。她要使用一种有效的工具,比如汽车或公共汽车,或者至少是一辆自行车,每天带她10英里去上班。

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

有几个框架旨在帮助程序员继续有效地练习坏习惯。

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

因此,结论性的答案...

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

嵌套在类文件中的适当命名的私有接口中的接口常量也是对所有私有常量进行分组而不是将它们分散在文件上的好方法。


推荐