在Java中实现常量的最佳方法是什么?

我见过这样的例子:

public class MaxSeconds {
public static final int MAX_SECONDS = 25;
}

假设我可以有一个Constants类来包装常量,并将它们声明为静态final。我几乎不知道Java,我想知道这是否是创建常量的最佳方式。

854736 次浏览

这完全可以接受,甚至可能是标准。

(public/private) static final TYPE NAME = VALUE;

其中TYPE是类型,NAME是全大写的名称,空格用下划线表示,VALUE是常量值;

我强烈建议不要将常量放在它们自己的类或接口中。

附注:声明为final且为mutable的变量仍然可以更改;但是,变量永远不能指向不同的对象。

例如:

public static final Point ORIGIN = new Point(0,0);


public static void main(String[] args){


ORIGIN.x = 3;


}

这是合法的,并且ORIGIN将是位于(3,0)的点。

我不会称这个类与常量相同(除了大小写)…我将至少有一类“设置”,或“值”,或“常量”,所有的常量都将存在。如果我有很多,我会将它们分组在逻辑常量类中(UserSettings, AppSettings等)。

这是正确的做法。

通常常量保存在单独的“constants”类中,因为它们是不可发现的。如果常量与当前类相关,那么保留它们有助于下一个开发人员。

只是要避免使用接口:

public interface MyConstants {
String CONSTANT_ONE = "foo";
}


public class NeddsConstant implements MyConstants {


}

这很诱人,但违反了封装,并且模糊了类定义的区别。

更进一步,您可以将全局使用的常量放在接口中,这样它们就可以在系统范围内使用。如。

public interface MyGlobalConstants {
public static final int TIMEOUT_IN_SECS = 25;
}

但是不要执行它。只需在代码中通过完全限定类名直接引用它们。

那么枚举呢?

我强烈建议不要只使用一个常量类。这在当时看起来是一个好主意,但是当开发人员拒绝记录常量,并且类增长到包含500个以上彼此完全不相关的常量(与应用程序的完全不同方面相关)时,通常会导致常量文件完全不可读。而不是:

  • 如果您可以访问Java 5+,可以使用枚举为应用程序区域定义特定的常量。对于这些常量,应用程序区域的所有部分都应该引用枚举,而不是常量值。可以像声明类一样声明枚举。枚举可能是Java 5+中最有用(也可以说是唯一)的特性。
  • 如果您拥有仅对特定类或其子类有效的常量,请将它们声明为protected或public,并将它们放置在层次结构的顶层类上。通过这种方式,子类可以访问这些常量值(如果其他类通过public访问它们,这些常量不仅对特定的类有效……这意味着使用该常量的外部类可能与包含该常量的类耦合过于紧密)
  • 如果您有一个定义了行为的接口,但是返回值或参数值应该是特定的,那么在该接口上定义常量以便其他实现者可以访问它们是完全可以接受的。但是,要避免仅仅为了保存常量而创建接口:它会变得和仅仅为了保存常量而创建的类一样糟糕。

它是一个不好的做法,只使用接口来保存常量(由Josh Bloch命名为固定接口模式)。以下是乔希的建议:

如果常量与 现有的类或接口 是否应该将它们添加到类中 接口。例如,所有的 盒装的数字基元类, 如Integer和Double,导出 MIN_VALUE和MAX_VALUE常量。如果 这些常数最好看成 枚举类型的成员 应该用枚举导出它们 类型。否则,您应该导出 带有不可实例化对象的常量 工具类。< / p >

例子:

// Constant utility class
package com.effectivejava.science;
public class PhysicalConstants {
private PhysicalConstants() { }  // Prevents instantiation


public static final double AVOGADROS_NUMBER   = 6.02214199e23;
public static final double BOLTZMANN_CONSTANT = 1.3806503e-23;
public static final double ELECTRON_MASS      = 9.10938188e-31;
}

关于命名约定:

按照约定,这些字段有名称 由大写字母组成的 用下划线分隔的单词。它是 重要的是,这些字段包含 要么是原始值,要么是引用

在Effective Java(第二版)中,建议对常量使用枚举而不是静态整型。

这里有一篇很好的关于Java中枚举的文章: http://java.sun.com/j2se/1.5.0/docs/guide/language/enums.html < / p >

请注意,在那篇文章的最后提出的问题是:

那么什么时候应该使用枚举呢?

答案为:

任何时候你需要一个固定的常数集

我同意使用界面不是正确的方法。避免这种模式甚至在Bloch的有效的Java中有自己的项目(#18)。

Bloch反对常量接口模式的一个论点是,常量的使用是一个实现细节,但是实现一个使用它们的接口会在导出的API中暴露该实现细节。

public|private static final TYPE NAME = VALUE;模式是声明常量的好方法。就我个人而言,我认为最好避免创建一个单独的类来存放所有的常量,但除了个人偏好和风格之外,我还没有看到不这样做的理由。

如果常量可以很好地建模为枚举,请考虑1.5或更高版本中可用的枚举结构。

如果您使用的是1.5以前的版本,您仍然可以通过使用普通的Java类来实现类型安全枚举。(详见这个网站)。

您可能犯的第一个错误是创建一个全局可访问的类,类名为泛型名称,如Constants。这只会充斥着垃圾,您将无法确定系统的哪个部分使用了这些常量。

相反,常量应该放到“拥有”它们的类中。有一个叫TIMEOUT的常量吗?它应该放到Communications()或Connection()类中。MAX_BAD_LOGINS_PER_HOUR吗?进入User()。诸如此类。

当“常量”可以在运行时定义,但用户不容易更改时,另一种可能的用法是Java .properties文件。你可以把它们打包到你的.jar文件中,并使用Class resourceLoader引用它们。

对于常量,Enum是一个更好的选择。这里有一个例子

公共类myClass {

public enum myEnum {
Option1("String1", 2),
Option2("String2", 2)
;
String str;
int i;


myEnum(String str1, int i1) { this.str = str1 ; this.i1 = i }




}

任何类型的常量都可以通过在类中创建一个不可变属性(即带有final修饰符的成员变量)来声明。通常还提供了staticpublic修饰符。

public class OfficePrinter {
public static final String STATE = "Ready";
}

在许多应用中,常量的值表示从n元组(例如枚举)中选择一个选项。在我们的例子中,我们可以选择定义一个枚举类型来限制可能分配的值(即改进的类型安全):

public class OfficePrinter {
public enum PrinterState { Ready, PCLoadLetter, OutOfToner, Offline };
public static final PrinterState STATE = PrinterState.Ready;
}

我这样做的方法之一是通过创建一个具有常量值的“全局”类,并在需要访问常量的类中进行静态导入。

单一的泛型常量类不是一个好主意。常量应该按照它们在逻辑上最相关的类来分组。

我建议您使用方法,而不是使用任何类型的变量(特别是枚举)。创建一个与变量同名的方法,并让它返回分配给变量的值。现在删除该变量,并将对它的所有引用替换为对刚才创建的方法的调用。如果您觉得常量足够通用,不应该为了使用它而创建类的实例,那么可以将常量方法作为类方法。

一个好的面向对象设计不应该需要很多公开可用的常量。大多数常量都应该封装在需要它们完成工作的类中。

我更喜欢使用getter而不是常量。这些getter可能返回常量值,例如public int getMaxConnections() {return 10;},但任何需要常量的东西都将通过getter。

一个好处是,如果您的程序超出了常量的使用范围——您发现它需要可配置——您可以更改getter返回常量的方式。

另一个好处是,为了修改常量,你不必重新编译所有使用它的东西。当引用静态final字段时,该常量的值将被编译到引用它的任何字节码中。

总之,以秒为单位的timeout值应该是一个配置设置(从属性文件中读取或像Spring中那样通过注入),而不是一个常量。

在单独的类中创建静态final常量可能会给您带来麻烦。Java编译器实际上会对此进行优化,并将常量的实际值放置到引用它的任何类中。

如果你稍后更改了Constants类,并且没有对引用该类的其他类进行严格的重新编译,那么你最终将使用新旧值的组合。

不要把它们看作常量,而应该把它们看作配置参数,并创建一个类来管理它们。让值是非final的,甚至可以考虑使用getter。将来,当您确定其中一些参数实际上应该由用户或管理员进行配置时,这将变得容易得多。

有什么不同

1.

public interface MyGlobalConstants {
public static final int TIMEOUT_IN_SECS = 25;
}

2.

public class MyGlobalConstants {
private MyGlobalConstants () {} // Prevents instantiation
public static final int TIMEOUT_IN_SECS = 25;
}
< p >和使用 MyGlobalConstants.TIMEOUT_IN_SECS当我们需要这个常量时。

根据上面的评论,我认为这是一个很好的方法,将老式的全局常量类(具有公共静态final变量)更改为类似枚举的等价物,如下所示:

public class Constants {


private Constants() {
throw new AssertionError();
}


public interface ConstantType {}


public enum StringConstant implements ConstantType {
DB_HOST("localhost");
// other String constants come here


private String value;
private StringConstant(String value) {
this.value = value;
}
public String value() {
return value;
}
}


public enum IntConstant implements ConstantType {
DB_PORT(3128),
MAX_PAGE_SIZE(100);
// other int constants come here


private int value;
private IntConstant(int value) {
this.value = value;
}
public int value() {
return value;
}
}


public enum SimpleConstant implements ConstantType {
STATE_INIT,
STATE_START,
STATE_END;
}


}

这样我就可以把它们引用为:

Constants.StringConstant.DB_HOST

我使用以下方法:

public final class Constants {
public final class File {
public static final int MIN_ROWS = 1;
public static final int MAX_ROWS = 1000;


private File() {}
}


public final class DB {
public static final String name = "oups";


public final class Connection {
public static final String URL = "jdbc:tra-ta-ta";
public static final String USER = "testUser";
public static final String PASSWORD = "testPassword";


private Connection() {}
}


private DB() {}
}


private Constants() {}
}

Than,例如,我使用Constants.DB.Connection.URL来获得常量。 对我来说,它看起来更“面向对象”

static final是我的偏好,如果项目确实是可枚举的,我只使用enum

我使用static final来声明常量,并使用ALL_CAPS命名符号。我在现实生活中见过很多实例,其中所有常量都聚集在一个接口中。一些帖子正确地称这是一种糟糕的做法,主要是因为这不是接口的作用。接口应该执行契约,而不应该是放置不相关常量的地方。如果常量语义不属于特定的类,那么将它们放在一个不能实例化(通过私有构造函数)的类中也是可以的。我总是在与它最相关的类中放置一个常量,因为这是有意义的,也容易维护。

枚举是表示一组值的好选择,但是如果您要存储强调绝对值的独立常量(例如。TIMEOUT = 100 ms)你可以直接使用static final方法。

我同意大多数人所说的,在处理常量集合时最好使用枚举。然而,如果你在Android上编程,有一个更好的解决方案:IntDef注释

@Retention(SOURCE)
@IntDef({NAVIGATION_MODE_STANDARD, NAVIGATION_MODE_LIST,NAVIGATION_MODE_TABS})
public @interface NavigationMode {}
public static final int NAVIGATION_MODE_STANDARD = 0;
public static final int NAVIGATION_MODE_LIST = 1;
public static final int NAVIGATION_MODE_TABS = 2;
...
public abstract void setNavigationMode(@NavigationMode int mode);
@NavigationMode
public abstract int getNavigationMode();

IntDef注释在一个简单的方面优于枚举,它占用的空间明显更少,因为它只是一个编译时标记。它不是一个类,也没有自动字符串转换属性。

有一定的观点来回答这个问题。首先,java中的常量通常被声明为public、static和final。原因如下:

public, so that they are accessible from everywhere
static, so that they can be accessed without any instance. Since they are constants it
makes little sense to duplicate them for every object.
final, since they should not be allowed to change

我永远不会为CONSTANTS访问器/对象使用接口,因为接口通常是需要实现的。这看起来是不是很有趣:

String myConstant = IMyInterface.CONSTANTX;

相反,我会在一些不同的方法中进行选择,基于一些小的权衡,所以这取决于你需要什么:

1.  Use a regular enum with a default/private constructor. Most people would define
constants this way, IMHO.
- drawback: cannot effectively Javadoc each constant member
- advantage: var members are implicitly public, static, and final
- advantage: type-safe
- provides "a limited constructor" in a special way that only takes args which match
predefined 'public static final' keys, thus limiting what you can pass to the
constructor


2.  Use a altered enum WITHOUT a constructor, having all variables defined with
prefixed 'public static final' .
- looks funny just having a floating semi-colon in the code
- advantage: you can JavaDoc each variable with an explanation
- drawback: you still have to put explicit 'public static final' before each variable
- drawback: not type-safe
- no 'limited constructor'


3.  Use a Class with a private constructor:
- advantage: you can JavaDoc each variable with an explanation
- drawback: you have to put explicit 'public static final' before each variable
- you have the option of having a constructor to create an instance
of the class if you want to provide additional functions related
to your constants
(or just keep the constructor private)
- drawback: not type-safe


4. Using interface:
- advantage: you can JavaDoc each variable with an explanation
- advantage: var members are implicitly 'public static final'
- you are able to define default interface methods if you want to provide additional
functions related to your constants (only if you implement the interface)
- drawback: not type-safe

在Java中实现常量的最佳方法是什么?

我们应该避免的一种方法:使用接口定义常量

创建一个专门用于声明常量的接口实际上是最糟糕的事情:它违背了设计接口的初衷:定义方法契约

即使接口已经存在以满足特定的需求,在其中声明常量也没有意义,因为常量不应该成为API和提供给客户端类的契约的一部分


为了简化,我们有4种有效的方法。< br >

使用static final String/Integer字段:

  • 1)使用在内部声明常量的类。
  • 1变体)创建一个专门用于声明常量的类。

使用Java 5 enum:

  • 2)在相关的目的类(嵌套类)中声明枚举。
  • 2变体)创建枚举作为一个独立的类(在它自己的类文件中定义)。

TLDR:哪个是最好的方法,在哪里找到常数?

在大多数情况下,枚举方式可能比static final String/Integer方式更好和我个人认为static final String/Integer方式应该只在我们有很好的理由不使用枚举时才使用 关于我们应该在哪里声明常量值,其思想是搜索是否存在一个现有的类,该类拥有特定的、具有常量值的强函数内聚。如果我们找到这样一个类,我们应该使用它作为常量的持有者。否则,该常量不应与任何特定的类相关联


__ABC0/ __ABC1相对于enum

枚举的使用确实是一种强烈考虑的方式 枚举比StringInteger常量字段有很大的优势。< br > 它们设置了更强的编译约束。 如果定义了一个以enum为参数的方法,则只能传递enum类中定义的enum值(或null)。< br > 对于String和Integer,你可以用任何兼容类型的值替换它们,即使该值不是static final String/ static final Integer字段中定义的常量,编译也会很好。< / p >

例如,下面两个在类中定义为static final String字段的常量:

public class MyClass{


public static final String ONE_CONSTANT = "value";
public static final String ANOTHER_CONSTANT = "other value";
. . .
}

下面是一个方法,它期望将这些常量中的一个作为参数:

public void process(String constantExpected){
...
}

你可以这样调用它:

process(MyClass.ONE_CONSTANT);

process(MyClass.ANOTHER_CONSTANT);

但是没有编译约束阻止你以这种方式调用它:

process("a not defined constant value");

只有在运行时才会出现错误,并且只有在一次检查传输的值时才会出现错误。

对于enum,不需要检查,因为客户端只能在enum参数中传递enum值

例如,这里有两个在枚举类中定义的值(所以是常量):

public enum MyEnum {


ONE_CONSTANT("value"), ANOTHER_CONSTANT(" another value");


private String value;


MyEnum(String value) {
this.value = value;
}
...
}

下面是一个方法,它期望将这些枚举值中的一个作为参数:

public void process(MyEnum myEnum){
...
}

你可以这样调用它:

process(MyEnum.ONE_CONSTANT);

process(MyEnum.ANOTHER_CONSTANT);

但是编译永远不会允许你以这种方式调用它:

process("a not defined constant value");

我们应该在哪里声明常数?

如果你的应用程序包含一个现有的类,它拥有一个特定的和强的函数内聚的常量值,1)和2)看起来更直观 一般来说,如果这些常量是在操纵它们的主类中声明的,或者有一个非常自然的名字,我们可以在里面找到它,那么使用这些常量会更容易

例如,在JDK库中,在一个不仅声明常量声明(java.lang.Math)的类中声明了指数和π常数值。

   public final class Math {
...
public static final double E = 2.7182818284590452354;
public static final double PI = 3.14159265358979323846;
...
}
使用数学函数的客户端通常依赖于Math类。 因此,他们可以很容易地找到常量,也可以非常自然地记住EPI是在哪里定义的。< br > < / p > 如果您的应用程序不包含一个现有的类,该类与常量值具有非常特定且强大的函数内聚性,则1 variant)和2 variant)方法看起来更直观 一般来说,如果在一个操纵常量的类中声明这些常量,而我们还有3或4个其他类同样地操纵它们,并且这些类中似乎没有一个比其他类更自然地容纳常量值,则不会简化常量的使用 在这里,定义一个自定义类来只保存常量值是有意义的 例如,在JDK库中,java.util.concurrent.TimeUnit枚举没有在特定的类中声明,因为实际上没有且只有一个JDK特定的类看起来是最直观地保存它:

public enum TimeUnit {
NANOSECONDS {
.....
},
MICROSECONDS {
.....
},
MILLISECONDS {
.....
},
SECONDS {
.....
},
.....
}
java.util.concurrent中声明的许多类都使用它们: __abc0, __abc1, __abc2, __abc3,…实际上,它们中似乎没有一个更适合保存枚举
这是一个非常坏的习惯 令人讨厌的做法引用约书亚·布洛赫的话,却不理解基本的零起点原教旨主义

我也没读过约书亚·布洛赫的书

  • 他是个糟糕的程序员
  • 或者迄今为止我发现引用他的人(约书亚是一个男孩的名字,我猜)只是把他的材料作为宗教脚本来证明他们的软件是宗教放纵的。

在圣经原教旨主义中,所有的圣经律法都可以总结为

  • 全心全意地爱根本身份
  • 爱邻居如爱自己

所以类似的软件工程原教旨主义可以总结为

  • 全身心地投入到编程的基础知识中
  • 像对待自己一样,为你的程序员同事的优秀而努力。

此外,在圣经原教旨主义的圈子中,一个强有力的合理的推论被得出

  • 首先爱自己。因为如果你不爱自己,那么“像爱自己一样爱邻居”的概念就没有多大分量,因为“你有多爱自己”是你爱别人的基准线。

类似地,如果你不尊重自己作为一个程序员,只是接受一些编程大师的声明和预言,而不质疑基本原理,你对Joshua Bloch的引用和依赖是毫无意义的。因此,你实际上不尊重你的程序员同事。

软件编程的基本法则

  • 懒惰是优秀程序员的美德
  • 你要让你的编程生活尽可能简单,尽可能懒惰,因此尽可能有效
  • 你要让你的编程结果和内脏尽可能简单,尽可能懒惰,因此对你的邻居程序员来说是尽可能有效的,他们和你一起工作,捡起你的编程内脏。

接口模式常量是个坏习惯??

在基本有效和负责任的编程法律下,这一宗教法令属于什么?

只要看看维基百科上关于接口模式常量(https://en.wikipedia.org/wiki/Constant_interface)的文章,以及它针对接口模式常量的愚蠢借口就知道了。

  • < p > Whatif-No IDE吗?作为软件程序员,究竟有谁不使用IDE?我们中的大多数人都是程序员,他们不喜欢通过避免使用IDE来证明自己有男子汉的审美生存主义。

    • 还有,等等,微函数编程的支持者认为它是一种不需要IDE的方法。等着看我对数据模型规范化的解释吧。
    • 李< / ul > < / >
    • 使用当前作用域内未使用的变量污染命名空间?它可能是这个观点的支持者

      • 没有意识到数据模型规范化的必要性吗
      • 李< / ul > < / >
      • 使用接口强制常量是对接口的滥用。这样的支持者有一个坏习惯

        • 没有看到“常量”必须被视为契约。接口用于执行或投射对契约的遵从性。
        • 李< / ul > < / >
        • 将来将接口转换为实现的类是困难的,如果不是不可能的话。哈……嗯…???

          • 为什么你想要从事这样的编程模式作为你持久的生计?低,为什么要把自己投入到这样一个矛盾的和坏的编程习惯?
          • 李< / ul > < / >

          无论借口是什么,当涉及到从根本上有效的软件工程时,都没有合理的借口来反对或通常不鼓励接口常量的使用。

          制定美国宪法的国父们的初衷和精神状态如何并不重要。我们可以讨论开国元勋们的初衷,但我关心的是美国宪法的书面声明。每一个美国公民都有责任利用美国宪法中书面的文学原教旨主义,而不是不成文的立国意图。

          类似地,我并不关心Java平台和编程语言的创始人对接口的“最初”意图是什么。我关心的是Java规范提供的有效功能,我打算充分利用这些功能来帮助我实现负责任的软件编程的基本法则。我不在乎我是否被认为“违反了接口的意图”。我不在乎Gosling或Bloch所说的“正确使用Java的方法”,除非他们所说的不违反我有效实现基本原理的需求。

          基础是数据模型规范化

          数据模型是如何托管或传输的并不重要。如果您不理解数据模型规范化的需求和过程,那么无论您使用接口、枚举还是其他什么,关系sql还是非sql。

          我们必须首先定义并规范化一组流程的数据模型。当我们有一个一致的数据模型时,只有这样我们才能使用其组件的流程流来定义应用程序的领域或领域的功能行为和流程块。只有这样,我们才能定义每个功能流程的API。

          甚至EF Codd提出的数据规范化方面现在也受到了严重的挑战。例如,他关于1NF的声明被批评为模棱两可、错位和过于简化,他的其他声明也是如此,特别是在现代数据服务、回购技术和传输的出现方面。在我看来,应该完全抛弃EF Codd语句,并设计一套新的数学上更合理的语句。

          EF Codd的一个突出缺陷及其与有效的人类理解不一致的原因是,他相信人类可感知的多维、可变维度数据可以通过一组零碎的2维映射有效地感知。

          数据规范化的基础

          EF Codd未能表达的。

          在每个连贯的数据模型中,这些是要实现的数据模型连贯的顺序递增顺序。

          1. 数据实例的Unity和Identity。
            • 设计每个数据组件的粒度,使其粒度处于可以唯一标识和检索组件的每个实例的级别。
            • 缺少实例别名。也就是说,一个标识不可能产生一个组件的多个实例。
            • 李< / ul > < / >
            • 没有实例串扰。不存在使用组件的一个或多个其他实例来帮助标识组件实例的必要性。
            • 数据组件/维度的统一和同一性。
              • 存在组件去锯齿。必须存在一个定义,其中可以唯一标识组件/维度。这是组件的主要定义;
              • 主定义不会导致暴露子维度或不属于预期组件的成员组件;
              • 李< / ul > < / >
              • 组件处理的独特方法。对于一个组件,必须存在且只有一个这样的组件去锯齿化定义。
              • 存在且仅有一个定义接口或契约,用于在组件的层次关系中标识父组件。
              • 无组件串扰。不存在使用另一个组件的成员来帮助确定组件的必要性。
                • 在这样的父子关系中,父对象的标识定义不能依赖于子对象的成员组件集的一部分。父标识的成员组件必须是完整的子标识,而不需要引用子标识的任何或所有子标识。
                • 李< / ul > < / >
                • 抢占数据模型的双模态或多模态外观。
                  • 当存在一个组件的两个候选定义时,这是一个明显的迹象,表明存在两个不同的数据模型被混合为一个。这意味着在数据模型级别或领域级别上存在不一致性。
                  • 一个应用领域必须连贯地使用一个且只有一个数据模型。
                  • 李< / ul > < / >
                  • 检测和识别成分突变。除非您对大量数据进行过统计成分分析,否则您可能看不到或看不到处理成分突变的必要性。
                    • 数据模型的一些组件可能周期性地或逐渐地发生变化。
                    • 模式可以是成员旋转或转位旋转。
                    • 成员旋转突变可以是组件之间子组件的不同交换。或者需要定义全新的组件。
                    • 换位突变表现为维度成员突变为属性,反之亦然。
                    • 每个突变周期必须被标识为不同的数据模式。
                    • 李< / ul > < / >
                    • 对每个突变进行版本化。这样,当可能需要处理数据模型的8年前的突变时,您就可以取出数据模型的以前版本。

          在相互服务的组件应用程序的字段或网格中,必须有且只有一个一致的数据模型,或者存在数据模型/版本标识自身的方法。

          我们还在问是否可以使用接口常量吗?真的吗?

          有一些数据规范化问题比这个平凡的问题更重要。如果您不解决这些问题,那么您认为接口常量所引起的混乱相对来说是微不足道的。无价值之物。

          根据数据模型归一化,然后将组件确定为变量、属性和契约接口常数。

          然后确定哪些是值注入、属性配置占位符、接口、最终字符串等等。

          如果您不得不以需要定位组件为借口,以便根据接口常量进行指示,这意味着您没有实践数据模型规范化的坏习惯。

          也许你希望将数据模型编译成一个风险投资版本。您可以提取数据模型的明确可识别版本。

          在接口中定义的值完全保证是不可变的。和共享。当你所需要的只是一组常量时,为什么要从另一个类加载一组最终字符串到你的类中呢?

          那么为什么不发布一个数据模型契约呢?我的意思是,如果你能连贯地管理和规范它,为什么不呢?...

          public interface CustomerService {
          public interface Label{
          char AssignmentCharacter = ':';
          public interface Address{
          String Street = "Street";
          String Unit= "Unit/Suite";
          String Municipal = "City";
          String County = "County";
          String Provincial = "State";
          String PostalCode = "Zip"
          }
          
          
          public interface Person {
          public interface NameParts{
          String Given = "First/Given name"
          String Auxiliary = "Middle initial"
          String Family = "Last name"
          }
          }
          }
          }
          

          现在我可以引用我的应用程序的合同标签的方式,如

          CustomerService.Label.Address.Street
          CustomerService.Label.Person.NameParts.Family
          

          这会混淆jar文件的内容?作为一个Java程序员,我不关心jar的结构。

          这给osgi驱动的运行时交换带来了复杂性?Osgi是一种非常有效的方法,可以让程序员继续他们的坏习惯。有比osgi更好的替代方案。

          或者为什么不是这个?没有私人常数泄漏到公开的合同。所有私有常量都应该分组到一个名为“constants”的私有接口中,因为我不想不得不搜索常量,而且我懒得重复键入“私有最终字符串”。

          public class PurchaseRequest {
          private interface Constants{
          String INTERESTINGName = "Interesting Name";
          String OFFICIALLanguage = "Official Language"
          int MAXNames = 9;
          }
          }
          

          甚至可能是这样:

          public interface PurchaseOrderConstants {
          public interface Properties{
          default String InterestingName(){
          return something();
          }
          String OFFICIALLanguage = "Official Language"
          int MAXNames = 9;
          }
          }
          

          接口常量唯一值得考虑的问题是何时实现接口。

          这不是接口的“初衷”吗?就像我关心国父们制定美国宪法的“初衷”,而不是最高法院如何解释美国宪法的书面条文??

          毕竟,我生活在自由的土地上,荒野和勇敢者的家园。勇敢、自由、狂野——使用界面。如果我的程序员同事拒绝使用高效和懒惰的编程方式,我是否有义务按照黄金法则降低我的编程效率以与他们保持一致?也许我应该,但那不是理想的情况。