Использование частного конструктора для предотвращения создания экземпляра класса?
Сейчас я думаю о добавлении частного конструктора в класс, который содержит только константы 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();
}
...
}