常量实用程序类中的最终关键字

在使用具有常量实用程序类的final关键字时,我们可以获得性能和/或任何其他好处的任何差异。 [此类仅包含静态最终字段和私有构造函数以避免对象创建]

public class ActionConstants { private ActionConstants() // Prevents instantiation { } public static final String VALIDFIRSTLASTNAME = "[A-Za-z0-9.\\s]+"; public static final String VALIDPHONENUMBER = "\\d{10}"; ... ... } 

只有差异才是最终的阶级

  public final class ActionConstants { private ActionConstants() // Prevents instantiation { } public static final String VALIDFIRSTLASTNAME = "[A-Za-z0-9.\\s]+"; public static final String VALIDPHONENUMBER = "\\d{10}"; ... ... } 

我想知道,使用final有什么好处,以及为常量定义类的正确方法是什么。

没有任何好处。 它不会改变有关static final属性的任何内容。

当一个类成为最终类时,编译器可以利用这个来实现可覆盖的方法(静态方法不能被覆盖,最好,它们在inheritance的类中隐藏它们)。

由于该类是final,因此编译器知道它的方法都不能被覆盖。 因此,它可以计算不需要生成多态代码的情况(即,代码在运行时根据对象实例找到覆盖方法的正确’版本’)。 因此,可以进行优化。

如果你想让一个类真正独特,你可以使用这样的东西:

 public enum ActionConstants { INSTANCE; public static final int cte1 = 33; public static final int cte2 = 34; } 

如果你对一个类实例不感兴趣,只需将所有常量放在一个接口中。

如果您正在寻求提高性能,那么最好先预编译您的模式

 public static final Pattern VALIDFIRSTLASTNAME = Pattern.compile("[A-Za-z0-9.\\s]+"); public static final Pattern VALIDPHONENUMBER = Pattern.compile("\\d{10}"); 

与使用正则表达式的成本相比,使用final或not是非常小的。

没有真正的好处,但它确实强化了你的期望,没有什么能扩展你的课程。 从长远来看,这可能会让您更容易搜索代码以获取常量的所有用法,因为它们将保证为XXX.abc而不是YYY.abc,其中YYY延伸为XXX。

你应该避免使用“常量类”。 这意味着糟糕的设计。 将常量放在与它们一起运行的类中。 避免使用公共常量。 它应该是例外,而不是正常的做法。

将类用于常量是不常见的。 在大多数情况下,使用接口。 这可以通过ActionConstants.VALIDFIRSTLASTNAME访问:

 public interface ActionConstants { static final String VALIDFIRSTLASTNAME = "[A-Za-z0-9.\\s]+"; static final String VALIDPHONENUMBER = "\\d{10}"; ... } 

从Java 5开始,您也可以使用枚举。 枚举可以具有成员或扩展function。

第二个示例使用一个简单的成员(如果您有不同的常量类型,这里使用通用方法,否则您也可以使用String成员):

 public enum ActionConstants { FIRSTLASTNAME("[A-Za-z0-9.\\s]+"), PHONENUMBER("\\d{10}"); private final Object value; private ActionConstants(Object value) { this.value= value; } @SuppressWarnings("unchecked") public  T getValue() { return (T)value; } } String value = ActionConstants.FIRSTLASTNAME.getValue(); 

当所有常量属于同一类型时,最后一个示例使用扩展function。 您可以像ActionConstants.PHONENUMBER.isValid("0800123456")一样使用它:

 public enum ActionConstants { FIRSTLASTNAME("[A-Za-z0-9.\\s]+"), PHONENUMBER("\\d{10}"); private final Pattern pattern; private ActionConstants(String pattern) { this.pattern = Pattern.compile(pattern); } public void isValid(String value) { return pattern.matcher(value).matches(); } } 

两个版本都允许使用静态导入。