it-swarm.cn

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

我见过这样的例子:

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

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

373
mk.

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

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

其中TYPEname__是类型,NAMEname__是所有大写字母的名称,下划线表示空格,VALUEname__是常量值;

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

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

例如:

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

public static void main(String[] args){

    Origin.x = 3;

}

这是合法的,然后Originname__将是(3,0)处的一个点。

403
jjnguy

我强烈建议不要有一个常量类。当时看起来似乎是一个好主意,但是当开发人员拒绝记录常量并且类增长到包含超过500个常量时,这些常量根本不相关(与应用程序的完全不同的方面有关),通常会变成完全不可读的常量文件。代替:

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

它是 BAD PRACTICE 使用接口来保存常量(命名为 常量接口模式 由Josh Bloch提供)。这是Josh建议的:

如果常量与现有类或接口紧密相关,则应将它们添加到类或接口。例如,所有带框的数字基本类(如Integer和Double)都会导出MIN_VALUE和MAX_VALUE常量。如果常量最好被视为枚举类型的成员,则应使用 enum type导出它们。否则,您应该使用不可实例化的实用程序类导出常量。

例:

// 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;
}

关于命名约定:

按照惯例,这些字段的名称由大写字母组成,单词由下划线分隔。这些字段包含原始值或对不可变对象的引用至关重要。

120
Marcio Aguiar

在Effective Java(第2版)中,建议您使用枚举而不是静态整数来表示常量。

这里有关于Java的枚举的好文章: http://Java.Sun.com/j2se/1.5.0/docs/guide/language/enums.html

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

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

答案是:

任何时候你需要一组固定的常量

36
shelfoo

只是避免使用界面:

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

public class NeddsConstant implements MyConstants {

}

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

21
stimpy

我使用以下方法:

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() {}
}

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

19
albus.ua

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

如果您稍后更改了“常量”类,并且您没有对引用该类的其他类进行硬重新编译,那么最终将使用旧值和新值的组合。

不要将它们视为常量,而应将它们视为配置参数并创建一个类来管理它们。这些值是非最终的,甚至考虑使用getter。将来,当您确定某些参数实际上应该由用户或管理员配置时,它将更容易实现。

17
Kevin Day

您可以犯的第一个错误是创建一个全局可访问的类,使用通用名称调用,如常量。这简直就是乱七八糟的垃圾,你失去了弄清楚系统中哪些部分使用这些常量的能力。

相反,常量应该进入“拥有”它们的类。你有一个名为TIMEOUT的常量吗?它可能应该进入您的Communications()或Connection()类。 MAX_BAD_LOGINS_PER_HOUR?进入User()。等等等等。

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

13
Yann Ramin

这是正确的方法。

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

6
Jason Cohen

我同意使用界面不是要走的路。避免这种模式甚至在Bloch的 Effective Java 中有自己的项目(#18)。

Bloch对常量接口模式的一个参数是使用常量是一个实现细节,但实现一个接口来使用它们会在导出的API中公开该实现细节。

public|private static final TYPE NAME = VALUE;模式是声明常量的好方法。就个人而言,我认为最好避免单独设置一个容纳所有常量的课程,但除了个人偏好和风格外,我从未见过不这样做的理由。

如果您的常量可以作为枚举进行良好建模,请考虑1.5或更高版本中可用的 enum 结构。

如果您使用的是1.5之前的版本,则仍然可以使用普通的Java类来提取类型安全枚举。 (参见 本网站 了解更多信息)。

5
Rob Dickerson

枚举怎么样?

5
Sébastien D.

我更喜欢使用getter而不是常量。那些吸气剂可能会返回常数值,例如public int getMaxConnections() {return 10;},但任何需要常数的东西都会经过一个吸气剂。

一个好处是,如果你的程序超出常量 - 你发现它需要是可配置的 - 你可以改变getter返回常量的方式。

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

5
big_peanut_horse

基于上面的评论,我认为这是一种很好的方法,可以将老式的全局常量类(具有公共静态最终变量)更改为类似枚举的等效类,方法如下:

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
4
Lorand Bendig

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

3
Bradley Harris

有一定的意见来回答这个问题。首先,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
2
djangofan

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

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

创建一个专门用于声明常量的接口实际上是最糟糕的事情:它破坏了接口设计的原因:定义方法合同。

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


为了简化,我们有广泛的4种有效方法

使用static final String/Integer字段:

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

使用Java 5 enum

  • 2)在相关目的类中声明枚举(以及嵌套类)。
  • 2变体)将枚举创建为独立类(在其自己的类文件中定义)。

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

在大多数情况下,枚举方式可能比static final String/Integer方式更精细 并且我个人认为只有在我们有充分理由不使用枚举时才应使用static final String/Integer方式。
关于我们应该在哪里声明常量值, 我们的想法是搜索是否存在一个具有恒定值的特定且强大的功能内聚的现有类。如果我们找到这样的类,我们应该使用它作为常量持有者 。否则,常量应该与任何特定类无关。


static final String/static final Integerenum

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

例如,在类中定义为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");

只有在运行时检查传输的值时才会出现错误。

使用枚举,不需要检查,因为客户端只能在枚举参数中传递枚举值。

例如,这里有两个在枚举类中定义的值(开箱即用):

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库中,指数和pi常量值在一个类中声明,该类不仅声明常量声明(Java.lang.Math)。

   public final class Math {
          ...
       public static final double E = 2.7182818284590452354;
       public static final double PI = 3.14159265358979323846;
         ...
   }

使用数学函数的客户端通常依赖于Math类。因此,他们可以很容易地找到常量,并且还可以记住以非常自然的方式定义EPI的位置。

如果您的应用程序不包含具有与常量值具有非常特定且强大的功能内聚力的现有类,则1个变体和2个变体)方式看起来更直观。
一般来说,如果在一个操作它们的类中声明它们,它们不会简化常量的使用,而我们还有3个或4个其他操作它们的类,并且这些类中没有一个似乎是比其他人更自然地承载恒定值。
在这里,定义一个只保留常量值的自定义类是有道理的。
例如,在JDK库中,Java.util.concurrent.TimeUnit枚举未在特定类中声明,因为实际上并不存在唯一一个JDK特定类,它看起来最直观地保存它:

public enum TimeUnit {
    NANOSECONDS {
      .....
    },
    MICROSECONDS {
      .....
    },
    MILLISECONDS {
      .....
    },
    SECONDS {
      .....
    },
      .....
}      

Java.util.concurrent中声明的许多类使用它们:BlockingQueueArrayBlockingQueue<E>CompletableFutureExecutorService,...实际上没有一个类似乎更适合保存枚举。

2
davidxxx

FWIW,以秒为单位的超时值应该是配置设置(从属性文件读入或通过Spring注入)而不是常量。

1
Tim Howland

有什么不同

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;
}

并在需要此常量的地方使用MyGlobalConstants.TIMEOUT_IN_SECS。我认为两者都是一样的。

1
chandrayya

单个通用常量类是个坏主意。常量应该与它们在逻辑上最相关的类组合在一起。

我建议您使用方法,而不是使用任何类型的变量(尤其是枚举)。创建一个与变量同名的方法,并让它返回您赋给变量的值。现在删除变量并用对刚刚创建的方法的调用替换对它的所有引用。如果您认为常量足够通用,您不必创建类的实例只是为了使用它,那么将常量方法作为类方法。

1
ab

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

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

有许多应用,其中常量值表示从n元组(例如 枚举 )选择中的选择。在我们的示例中,我们可以选择定义一个枚举类型,它将限制可能的赋值(即改进的 type-safety ):

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

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

0
Joel Martinez

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

0
wulfgarpro

这是 坏习惯和非常恼人的练习 引用Joshua Bloch而不理解基本的零基本原理。

我还没有读过Joshua Bloch的任何内容

  • 他是一个可怕的程序员
  • 或者到目前为止我找到引用他的人(约书亚是我认为的男孩的名字)只是用他的材料作为宗教文字来证明他们的软件宗教嗜好是正当的。

正如圣经原教旨主义一样,所有圣经的律法都可以归结为

  • 全心全意地爱着基本身份
  • 爱自己的邻居

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

  • 用你所有的编程可能和思想来投入零基础
  • 并像你自己一样,致力于为你的同事们提供卓越的服务。

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

  • 初恋自己。因为如果你不爱自己,那么“爱你的邻居就像你自己”这个概念并没有太大的重要性,因为“你爱自己多少”是你会爱上别人的基准线。

同样,如果你不尊重自己作为一个程序员,只是接受一些编程大师的声明和预言而不询问基本原则,你的引用和对Joshua Bloch(等等)的依赖是毫无意义的。因此,你实际上不会尊重你的同事。

软件编程的基本规律

  • 懒惰是优秀程序员的美德
  • 你要让你的编程生活变得简单,懒惰,因此尽可能有效
  • 你要使你的编程的后果和内容变得简单,懒惰,因此尽可能有效地为你的neigbour程序员提供服务并获取你的编程内容。

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

根据什么样的基本有效和负责任的节目制定这个宗教法令?

只需阅读关于接口模式常量的维基百科文章( https://en.wikipedia.org/wiki/Constant_interface ),以及它对接口模式常量的愚蠢借口。

  • Whatif-No IDE?作为软件程序员,谁在地球上不会使用IDE?我们大多数人都是程序员,他们宁愿不必证明具有男子气概的认知生存主义,而不是使用IDE。

    • 此外 - 等待第二个微功能编程的支持者作为不需要IDE的手段。等到你阅读我对数据模型规范化的解释。
  • 使用当前范围内未使用的变量污染命名空间?它可能是这种观点的支持者

    • 不知道和需要数据模型规范化
  • 使用接口来强制执行常量是滥用接口。支持者有这样的坏习惯

    • 没有看到“常数”必须被视为合同。接口用于强制执行或预测合同的合规性。
  • 将来很难将接口转换为已实现的类。哈......嗯...... ???

    • 你为什么要像持续的生计那样参与这种编程模式? IOW,为什么要投身于这样一个AMBIVALENT和糟糕的编程习惯?

无论有什么借口,对于基本有效的软件工程来说,没有任何有效的排除可以使用或者通常不鼓励使用界面常量。

制定美国宪法的创始人的原始意图和心理状态是什么并不重要。我们可以辩论创始人的原始意图,但我所关心的只是美国宪法的书面陈述。每个美国公民都有责任利用美国宪法中的书面文学原教旨主义,而不是不成文的创始意图。

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

基础是数据模型规范化

托管或传输数据模型无关紧要。如果您不了解数据模型规范化的需要和过程,是使用接口还是枚举或whatevernot,关系型还是非SQL。

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

即使是EF Codd提出的数据规范化的各个方面,现在也面临严峻挑战和严峻挑战。例如他对1NF的陈述被批评为含糊不清,错位和过度简化,以及他的其他陈述,尤其是现代数据服务,回购技术和传播的出现。 IMO,EF Codd语句应该被完全抛弃,并且设计一组新的数学上合理的语句。

EF Codd's的一个明显缺陷及其与有效人类理解错位的原因是他相信人类可感知的多维,可变维数据可以通过一组零碎的二维映射有效地被感知。

数据规范化的基本原理

EF Codd未能表达的意思。

在每个相干数据模型中,这些是数据模型一致性的顺序分级顺序。

  1. 数据实例的统一性和身份。
    • 设计每个数据组件的粒度,从而使其粒度处于可以唯一标识和检索组件的每个实例的级别。
    • 没有实例别名。即,没有任何手段可以使识别产生一个以上的组件实例。
  2. 没有实例串扰。不存在使用组件的一个或多个其他实例来帮助识别组件的实例的必要性。
  3. 数据组件/维度的统一性和同一性。
    • 存在组件去混叠。必须存在一个定义,其中可以唯一地标识组件/维度。哪个是组件的主要定义;
    • 其中主要定义不会导致暴露不属于预期组件的子维度或成员组件;
  4. 组件去除的独特方法。必须存在一个且仅有一个组件的组件去混叠定义。
  5. 存在一个且仅有一个定义接口或合同来标识组件的层次关系中的父组件。
  6. 没有组件串扰。没有必要使用另一个组件的成员来帮助确定组件的确定性。[。_____。]
    • 在这种父子关系中,父母的识别定义不得依赖于儿童的一部分成员组成部分。父母身份的成员组成部分必须是完整的子身份,而无需借助于引用孩子的任何或所有孩子。
  7. 数据模型的轻微双模态或多模态外观。[。_____。]
    • 当存在两个组件的候选定义时,显然有两个不同的数据模型被混合为一个。这意味着数据模型级别或字段级别存在不连贯性。
    • 应用领域必须连贯地使用一个且仅一个数据模型。
  8. 检测并识别组件突变。除非您对大量数据进行了统计分量分析,否则您可能看不到或看到需要处理组件变异。[。_____。]
    • 数据模型可能使其某些组件周期性地或逐渐地发生变异。
    • 该模式可以是成员旋转或换位旋转。
    • 成员轮换突变可以是组件之间的子组件的不同交换。或者必须定义全新组件的地方。
    • 转换突变将表现为维度成员变异为属性,反之亦然。
    • 必须将每个突变周期识别为不同的数据模态。
  9. 对每个突变进行版本化这样您就可以提取数据模型的先前版本,或许需要处理数据模型的8年变异。

在服务间组件应用程序的字段或网格中,必须存在一个且仅一个相干数据模型,或者存在用于标识数据模型/版本的装置。

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

有些数据规范化问题比这个世俗问题更重要。如果你没有解决这些问题,那么你认为界面常数引起的混乱就相当没有了。小人物。

从数据模型规范化开始,然后将组件确定为变量,将属性确定为合约接口常量。

然后确定哪个进入值注入,属性配置占位,接口,最终字符串等。

如果你不得不使用需要定位组件更容易指示接口常量的借口,那就意味着你养成了不练习数据模型规范化的坏习惯。

也许您希望将数据模型编译为vcs版本。您可以提取数据模型的明显可识别版本。

接口中定义的值完全保证不可变。并且可以分享。当你需要的是那组常量时,为什么要从另一个类中将一组最终字符串加载到你的类中?

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

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更好的选择。

或者为什么不呢?私人常数没有泄露到公布的合同中。所有私有常量应该被分组到一个名为“常量”的私有接口,因为我不想搜索常量而且我懒得重复输入“private final String”。

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;
  }
}

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

这不是接口的“初衷”吗?就像我会关心创始人制定美国宪法的“初衷”,而不是最高法院如何解释美国宪法的书面信件?

毕竟,我生活在自由,野性和勇敢之家的土地上。勇敢,自由,狂野 - 使用界面。如果我的同事们拒绝使用高效和懒惰的编程方法,那么我是否有必要通过黄金法则来降低我的编程效率以与他们的编程保持一致?也许我应该,但这不是一个理想的情况。

0
Blessed Geek

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

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

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

0
Andrew Harmel-Law

我使用static final声明常量并使用ALL_CAPS命名表示法。我已经看到了很多真实生活实例,其中所有常量都聚集在一起形成一个接口。一些帖子正确地称这是一种不好的做法,主要是因为这不是一个界面的用途。接口应该强制执行一个契约,并且不应该放置不相关的常量。如果常量语义不属于特定的类,那么将它放在一个无法实例化的类中(通过私有构造函数)也是可以的。 ES)。我总是在课堂上放一个与它最相关的常数,因为这是有道理的,也很容易维护。

枚举是表示一系列值的不错选择,但如果要存储独立常量并强调绝对值(例如,TIMEOUT = 100 ms),您可以选择static final方法。

0
bincob

对于常数,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 }


}
0
mmansoor

我同意大多数人所说的,最好在处理常量集合时使用枚举。但是,如果您使用Android进行编程,则有更好的解决方案: IntDef Annotation

@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注释以一种简单的方式优于枚举,它占用的空间显着减少,因为它只是一个编译时标记。它不是一个类,也没有自动字符串转换属性。

0
Quinn Turner

我这样做的一种方法是使用常量值创建一个'Global'类,并在需要访问常量的类中进行静态导入。

0
Javamann