在 Java 中跨多个类共享常量字符串?

2022-08-31 15:50:02

我希望在一个地方有Java常量字符串,并在整个项目(许多类)中使用它们。

实现此目的的推荐方法是什么?


答案 1
public static final String CONSTANT_STRING="CONSTANT_STRING";

常量应为:

  1. 公共 - 以便可以从任何地方访问它
  2. 静态 - 无需创建实例
  3. final - 因为它的常量不应该被允许改变
  4. 根据Java命名约定,应大写,以便于阅读并在Java文档中脱颖而出。

在某些情况下,接口仅用于保持常量,但这被认为是一种不好的做法,因为接口应该定义类型的行为。

更好的方法是将其保留在更有意义的类中。

例如:

JFrame有contant,任何子类可以访问它,并且保留而不是在里面也是有意义的,因为并非所有组件都可以选择关闭。EXIT_ON_CLOSEJFrameJFrameJComponent


答案 2

正如@mprabhat之前回答的那样,常量应为 、 、,并用大写字母键入。publicstaticfinal

将它们分组到一个类中有助于:

  1. 不需要知道你拥有的所有常量。许多IDE(如Eclipse)向您显示一个类具有的所有字段的列表。因此,您只需按下并获取可以使用哪些常量的线索。CTRL+SPACE

  2. 使它们在编译时保持类型安全。如果您使用 s,则可能会拼错 ,并且仅在执行期间才注意到(如果您很幸运并且根本没有注意到它)。您还可以从自动完成中获利。String"DATABASE_EXCEPTION""DATABSE_EXSCEPTION"

  3. 帮助您在执行期间节省内存。您只需要 1 个常量实例的内存。即:(一个真实的例子)如果你在代码中的不同类中有“DATABASE_EXCEPTION”1000次,那么它们中的每一个在内存中都会是不同的。String

您可能还有其他一些注意事项:

  1. 添加javadoc注释,以便使用这些常量的程序员可以对常量有更多的语义信息。当您按 时,它显示为工具提示。即:CTRL+SPACE

    /** Indicates an exception during data retrieving, not during connection. */
    public static final String DATABASE_EXCEPTION = "DATABASE_EXCEPTION";
    /** Indicates an exception during the connection to a database. */
    public static final String DATABASE_CONNECTION_EXCEPTION =" DATABASE_CONNECTION_EXCEPTION";
    
  2. 向常量的标识符添加语义。如果你有常量,有时意味着,其他时间是年,请考虑使用2个不同的常量。"Y"

    public static final String Y = "Y"; // Bad
    public static final String YEAR = "Y";
    public static final String YES = "Y"; 
    

    如果将来决定更改常量的值,它将对您有所帮助。

    /** Year symbol, used for date formatters. */
    public static final String YEAR = "A"; // Year is Año, in Spanish.
    public static final String YES = "S"; // Yes is Sí, in Spanish.
    
  3. 在运行时之前,您可能不知道常量的值。IE:您可以从配置文件中读取它们。

    public class Constants
    {
      /** Message to be shown to the user if there's any SQL query problem. */
      public static final String DATABASE_EXCEPTION_MESSAGE; // Made with the 2 following ones.
      public static final String DATABASE_EXCEPTION = "DATABASE_EXCEPTION";
      public static final String MESSAGE = "MESSAGE";
    
      static {
        DATABASE_EXCEPTION_MESSAGE = DATABASE_EXCEPTION + MESSAGE; // It will be executed only once, during the class's [first] instantiation.
      }
    

    }

  4. 如果你的常量类太大,或者你认为它将来会增长太多,你可以把它分成不同的类,以获得不同的含义(再次,语义):,,等等。ConstantDBConstantNetwork

缺点:

  1. 团队的所有成员都必须使用相同的类,并对常量使用相同的命名法。在大型项目中,找到2个定义并不奇怪:

    public static final String DATABASE_EXCEPTION = "DATABASE_EXCEPTION";
    public static final String EXCEPTION_DATABASE = "DATABASE_EXCEPTION"; 
    

    分隔了几百行或不同的常量类。或者更糟糕的是:

    /** Indicates an exception during data retrieving, not during connection. */
    public static final String DATABASE_EXCEPTION = "DATABASE_EXCEPTION";
    /** Indicates an exception during data retrieving, not during connection. */
    public static final String EXCEPTION_DATABASE = "EXCEPTION_DATABASE"; 
    

    不同的标识符,用于不同的值,具有相同的含义(并用于相同的目的)。

  2. 它可能会使可读性变差。为了做同样的事情,必须写更多:

    if ("Y".equals(getOptionSelected()) {
    

    if (ConstantsWebForm.YES.equals(getOptionSeleted()) {
    
  3. 常量在类中应该如何排序?按字母顺序?所有相关常量在一起?按照创建/需要的顺序?谁来负责秩序的正确性呢?任何(足够大的)常量重新排序都会被视为版本控制系统中的混乱。

好吧,它花费的时间比我预期的要长。欢迎任何帮助/批评。