繁体   English   中英

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

[英]Final Keyword in Constant utility class

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

public class ActionConstants {
    private ActionConstants()  // Prevents instantiation
    {   }

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

唯一的区别是 class 最终确定

 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 有什么好处吗?为常量定义 class 的正确方法是什么。

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

当 class 成为 final 时,编译器可以利用这一点来覆盖可覆盖的方法(静态方法不能被覆盖,充其量,它们将那些隐藏在继承类中)。

由于 class 是最终的,编译器知道它的任何方法都不能被覆盖。 因此,它可以计算不需要生成多态性代码的情况(即,在运行时根据 object 实例找到覆盖方法的正确“版本”的代码)。 因此,优化是可能的。

如果你想让 class 真正独一无二,你可以使用这样的东西:

public enum ActionConstants {

    INSTANCE;

    public static final int cte1 = 33;
    public static final int cte2 = 34;

}

如果您对 class 实例根本不感兴趣,只需将所有常量放在接口中即可。

如果您正在寻找改进的性能,您最好预先编译您的模式,例如

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

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

没有真正的好处,但它确实强制您期望没有任何东西可以扩展您的 class。 从长远来看,这可能会更容易,例如,在代码中搜索常量的所有用途,因为它们将被保证为 XXX.abc 而不是 YYY.abc,其中 YYY 扩展了 XXX。

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

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

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

由于 Java 5 你也可以使用枚举。 枚举可以有成员或扩展功能。

第二个示例使用一个简单的成员(如果您有不同的常量类型,这里使用通用方法,否则您也可以使用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> T getValue() {
    return (T)value;
  }

}

String value = ActionConstants.FIRSTLASTNAME.getValue();

最后一个示例在所有常量都属于同一类型时使用扩展功能。 您可以像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();
  }

}

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM