我见过这样的例子:

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

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


当前回答

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

If you have access to Java 5+, use enums to define your specific constants for an application area. All parts of the application area should refer to enums, not constant values, for these constants. You may declare an enum similar to how you declare a class. Enums are perhaps the most (and, arguably, only) useful feature of Java 5+. If you have constants that are only valid to a particular class or one of its subclasses, declare them as either protected or public and place them on the top class in the hierarchy. This way, the subclasses can access these constant values (and if other classes access them via public, the constants aren't only valid to a particular class...which means that the external classes using this constant may be too tightly coupled to the class containing the constant) If you have an interface with behavior defined, but returned values or argument values should be particular, it is perfectly acceptible to define constants on that interface so that other implementors will have access to them. However, avoid creating an interface just to hold constants: it can become just as bad as a class created just to hold constants.

其他回答

有什么不同

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,我们需要这个常量。我认为两者是一样的。

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

If you have access to Java 5+, use enums to define your specific constants for an application area. All parts of the application area should refer to enums, not constant values, for these constants. You may declare an enum similar to how you declare a class. Enums are perhaps the most (and, arguably, only) useful feature of Java 5+. If you have constants that are only valid to a particular class or one of its subclasses, declare them as either protected or public and place them on the top class in the hierarchy. This way, the subclasses can access these constant values (and if other classes access them via public, the constants aren't only valid to a particular class...which means that the external classes using this constant may be too tightly coupled to the class containing the constant) If you have an interface with behavior defined, but returned values or argument values should be particular, it is perfectly acceptible to define constants on that interface so that other implementors will have access to them. However, avoid creating an interface just to hold constants: it can become just as bad as a class created just to hold constants.

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

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

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

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

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

根据上面的评论,我认为这是一个很好的方法,将老式的全局常量类(具有公共静态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