Использование частного конструктора для предотвращения создания экземпляра класса?

Сейчас я думаю о добавлении частного конструктора в класс, который содержит только константы String.

public class MyStrings {
  // I want to add this:
  private MyString() {}

  public static final String ONE = "something";
  public static final String TWO = "another";
  ...
}

Есть ли какой-либо производительность или память, если я добавлю частный конструктор в этот класс, чтобы кто-то не смог его создать?

Считаете ли вы, что это необходимо вообще или что частные конструкторы для этой цели являются пустой тратой времени и беспорядка кода?

UPDATE

Я собираюсь для окончательного класса с частным конструктором и описательным javadoc для класса. Я не могу использовать ENUM (что я бы предпочел), потому что сейчас я застрял на Java 1.4. Это будет моя модификация:

/**
 * Only for static access, do not instantiate this class.
 */
public final class MyStrings {
  private MyString() {}

  public static final String ONE = "something";
  public static final String TWO = "another";
  ...
}

Ответы

Ответ 1

Использование частного конструктора для предотвращения создания экземпляра класса?

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

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

Ответ 2

Вы можете добавить частный конструктор, но есть еще два варианта.

В той же ситуации я бы использовал перечислитель. Если это имеет смысл для вашей реализации, вы можете использовать это вместо этого, если он public или private зависит от того, где вам нужно его использовать:

public enum MyStrings {

  ONE ("something"),

  TWO ("something else");

  private String value;

  private MyStrings(String str) {
     this.value = str;
  }

}

Другой вариант - поместить его в класс abstract, который не может быть создан:

public abstract MyStrings {

  public static final String STUFF = "stuff";
  public static final String OTHER = "other stuff";
}

Доступ как для счетчика, так и для абстрактного класса работает так же, как и при реализации, которую вы представили:

MyStrings.STUFF

Ответ 3

Если вы не станете кем-либо создавать объект класса, вы можете сделать его абстрактным, как это.

public abstract class MyStrings {
  public static final String ONE = "something";
  public static final String TWO = "another";
}

и получите доступ к вашим статическим переменным, таким как

String val1 = MyStrings.ONE;
String val2 = MyStrings.TWO;

Я думаю, что это было бы более приятным решением.

Ответ 4

Я предпочел бы использовать перечисление для хранения этих строк. Это обеспечит, чтобы везде, где вы используете эти строки, вы получаете только один из разрешенных строк.

Ответ 5

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

Ответ 6

Если ваш класс имеет только статические члены, тогда нет необходимости иметь частный или публичный конструктор. Все участники доступны даже без объекта. На самом деле я сбиваю с толку конструктор в таком случае.

Ответ 7

Синтетический публичный конструктор был бы сгенерирован любым способом. Так что нет.

Действительно, несколько байтов из сотен миллионов во время выполнения не будут иметь большого значения.

Я также предлагаю сделать класс final, и только для полноты конструктор выдает исключение.

Если вы хотите использовать краткий исходный код, вы можете создать перечисление без значений. Однако может возникнуть путаница с начинающими программистами.

Ответ 8

Правильный способ хранения некоторых констант, также предложенный в "Эффективной Java" (2-е изд.), пункт 19.

Ответ 9

Для меня лучшее объяснение в книге Эффективная Java: Пункт 4: Обеспечить неинтуитивность с помощью частного конструктора (Подробнее)

В резюме:

  • Частный конструктор из классов утилиты не был создан для создания экземпляра, поэтому это дизайнерское решение. (НЕТ производительности или служебных данных памяти)
  • Создание абстрактного класса не работает, потому что может быть подклассом, а затем создаваться экземпляром.
  • С абстрактным классом пользователь может подумать, что класс предназначен для наследования.
  • Единственный способ гарантировать отсутствие инстанцирования - добавить private constructor, который гарантирует, что конструктор по умолчанию не будет создан.
  • Частный конструктор предотвращает наследование, потому что супер-конструктор не может быть вызван (поэтому нет необходимости объявлять класс как final)
  • Выбросить ошибку в приватном конструкторе, избегать вызова его внутри класса.

Дефинитивно, лучший способ был бы следующим:

public class MyStrings {

     private MyStrings () {
       throw new AssertionError();
     }
      ... 
 }