Заключительное ключевое слово в служебном классе Constant - PullRequest
4 голосов
/ 26 мая 2011

Разница в производительности и / или любые другие преимущества, которые мы можем получить при использовании ключевого слова 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}";
    ...
    ...
}

Только diffrence класс является окончательным

 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 и как правильно определить класс для констант.

Ответы [ 5 ]

5 голосов
/ 26 мая 2011

Там нет никакой выгоды.Это ничего не меняет в отношении ваших атрибутов static final.

Когда класс становится финальным, компилятор может воспользоваться этим для переопределяемых методов (статические методы не могут быть переопределены, в лучшем случае они скрывают их вунаследованные классы).

Поскольку класс является окончательным, компилятор знает, что ни один из его методов не может быть переопределен.Таким образом, он может вычислять случаи, когда код полиморфизма не нужно генерировать (т. Е. Код, находящий правильную «версию» переопределяющего метода в соответствии с экземпляром объекта во время выполнения).Следовательно, возможна оптимизация.

Если вы хотите сделать класс по-настоящему уникальным, вы можете использовать что-то вроде этого:

public enum ActionConstants {

    INSTANCE;

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

}

И если вас не интересует экземпляр класса ввсе, просто поместите все свои константы в интерфейс.

3 голосов
/ 26 мая 2011

Если вы ищете улучшенную производительность, вам лучше предварительно скомпилировать шаблоны, например

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

Использование финала или нет, очень мало по сравнению со стоимостью использования регулярного выражения.

1 голос
/ 26 мая 2011

Вы должны избегать использования "классов для констант".Это означает плохой дизайн.Поместите константы в классы, которые работают с ними.Также избегайте использования публичных констант.Это должно быть исключением, а не обычной практикой.

1 голос
/ 26 мая 2011

Реальной выгоды нет, но она оправдывает ваши ожидания, что ничто не расширяет ваш класс.Это может упростить в долгосрочной перспективе, например, поиск в вашем коде всех вариантов использования констант, поскольку они гарантированно будут иметь значение XXX.abc, а не YYY.abc, где YYY расширяет XXX.

0 голосов
/ 26 мая 2011

Использовать класс для констант редко.В большинстве случаев используется интерфейс.Это будет доступно по ActionConstants.VALIDFIRSTLASTNAME:

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

Начиная с Java 5 вы также можете использовать enum.Перечисление может иметь члены или расширенную функциональность.

Во втором примере используется простой член (здесь с универсальным подходом, если у вас разные типы констант, иначе вы также можете использовать 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();
  }

}

Обе версии позволяют использовать статический импорт.

...