Конструктор Java и статический метод
Когда я должен использовать конструктор и когда должен использовать статический метод?
Можете ли вы объяснить это с помощью небольшого фрагмента? Я просмотрел несколько потоков, но я до сих пор не понимаю этого.
Ответы
Ответ 1
Используйте публичный конструктор, когда вы только хотите вернуть новый объект, который вам нужен, и вы хотите простоту.
Хорошим примером является StringBuilder, поскольку он изменен, и вы, вероятно, захотите новый объект каждый раз.
public String toString() {
StringBuilder sb = new StringBuilder();
// append fields to the sb
return sb.toString();
}
Использовать метод статического фактора, если вы захотите повторно использовать объекты (esp, если они неизменны), вы можете захотеть вернуть подкласс или хотите построить конструкцию. Хорошим примером является EnumSet, который имеет множество статических фабрик, которые выполняют разные вещи, хотя некоторые из них имеют одинаковые аргументы.
EnumSet.noneOf(RetentionPolicy.class);
// has the same arguments, but is not the same as
EnumSet.allOf(RetentionPolicy.class);
В этом случае использование статического factory позволяет понять, какая разница между этими двумя способами построения набора.
Также EnumSet может возвращать две разные реализации: одну оптимизированную для перечислений с небольшим количеством значений (< = 64) RegularEnumSet
и другое для многих значений, называемых JumboEnumSet
Ответ 2
Джошуа Блох советует использовать статические методы factory вместо конструкторов (что, по моему мнению, является хорошей практикой). Совокупность преимуществ и недостатков:
Преимущества статических factory методов:
- В отличие от конструкторов, они имеют имена
- В отличие от конструкторов, они не обязаны создавать новый объект при каждом вызове (вы можете кэшировать экземпляры: например,
Boolean.valueOf(..)
- В отличие от конструкторов, они могут возвращать объект любого подтипа возвращаемого типа (большая гибкость).
Недостатки статических методов factory:
- Они не отличаются от других статических методов (трудно узнать, как инициализировать объект, если вы не знакомы с API)
- Основной недостаток (если вы используете только статические методы factory, а make constructors private) - это то, что вы не можете подклассифицировать этот класс.
Ответ 3
Всегда используйте конструктор, если ваш класс имеет состояние (даже для одного экземпляра, singleton pattern).
Используйте только static для служебных методов, например, в java.lang.Math
Пример:
public static int max(int a, int b) {
return (a >= b) ? a : b;
}
Не меняет никакого состояния (переменные экземпляра) объекта, поэтому его можно объявить статическим.
Ответ 4
Статические методы factory имеют имена, конструкторы - нет. Таким образом, методы factory могут нести естественную документацию о том, что они делают, что конструкторы не могут. Например, см. Методы factory в библиотеках Guava, например ImmutableMap.copyOf(otherMap)
. Хотя это может мало повлиять на поведение конструкции, оно оказывает огромное влияние на читаемость кода. Определенно рассмотрите это, если вы публикуете API.
Также вы можете использовать factory, когда вам нужно выполнить более сложную конфигурацию создаваемого объекта, особенно если вам нужно публиковать в других потоках (регистрируясь в пулах, выставляя в качестве MBean всевозможные другие вещи...), чтобы избежать радикальной публикации. (См., Например, Java Concurrency В разделе Практика 3.2)
Статические методы, которые что-то делают (например, Math.min
), на самом деле не то же самое, что статические фабрики, которые можно считать прямыми заменами для конструкторов, с добавленной гибкостью, изменчивостью и (часто) ясностью.
Ответ 5
- Используйте конструктор, когда вам нужен объект и другие вещи, такие как функции и переменные, имеющие одну копию для каждого объекта.
-
когда вы хотите что-то сделать без создания объекта, используйте статический метод.
Example:
public class Test {
public int value;
public static int staticValue;
public int getValue() {
return ++value;
}
public static int getStaticValue() {
return ++staticValue;
}
}
public class TestClass {
public static void main(String[] args) {
Test obj = new Test();
Test obj1 = new Test();
S.o.p(obj.getValue());
S.o.p(obj1.getValue));
S.o.p(Test.getStaticValue());
S.o.p(Test.getStaticValue());
}
}
Ответ 6
Всякий раз, когда вам нужно создать экземпляр объекта, вам придется использовать конструктор.
Итак, если вы хотите создать объект Car, для этого вам понадобится конструктор.
Ключевое слово static означает, что ваш метод можно вызвать без создания экземпляра.
Ответ 7
class Car
{
private int num_of_seats;
public Car(int number_of_seats)
{
this.num_of_seats = number_of_seats;
}
// You want to get the name of the class that has to do with
// this class, but it not bounded with any data of the class
// itself. So you don't need any instance of the class, and
// you can declare it as static.
static String getClassName()
{
return "[Car]";
}
}
В общем случае вы будете использовать статический класс с данными, которые не коррелируют с экземпляром объекта.
Другой пример:
class Ring
{
private List nodes;
public Ring(List nodes)
{
this.nodes = nodes;
}
// You want to calculate the distance of two ids on the ring, but
// you don't care about the ring. You care only about the ids.
// However, this functionality logical falls into the notion of
// the ring, that why you put it here and you can declare it
// as static. That way you don't have to manage the instance of
// ring.
static double calculateDistance(int id_1, int id_2)
{
return (id_1 - id_2)/383; // The divisor is just random just like the calculation.
}
}
Как говорится выше, это просто вопрос того, что вы хотите сделать и как вы хотите это сделать. Кроме того, не пытайтесь все понять сразу, напишите какой-то код, затем попробуйте разные подходы к этому коду и попытайтесь понять, что делает ваш код. Примеры хороши, но вам нужно написать, а затем понять, что вы сделали. Я думаю, что это единственный способ выяснить
почему вы делаете персонал так, как вам нужно.
Ответ 8
Статические методы не должны создавать новые объекты каждый раз. Поскольку объект-экземпляр стоит дорого, он позволяет экземплярам кэшироваться внутри объекта. Таким образом, он может повысить производительность.
Это объяснение из Эффективная Java:
Это позволяет неизменным классам (пункт 15) использовать предварительно сконструированные экземпляры или кэшировать экземпляры по мере их создания и выдавать их неоднократно, чтобы избежать создания ненужных повторяющихся объектов. Метод Boolean.valueOf(boolean) иллюстрирует эту технику: он никогда создает объект. Этот метод похож на шаблон Flyweight [Gamma95, p. 195]. Это может значительно повысить производительность, если эквивалент объекты запрашиваются часто, особенно если они дороги создать.
Ответ 9
то есть. если вы хотите использовать синглтон, что означает, что у вас есть только один экземпляр объекта, который может быть передан другим, тогда вам понадобится статический метод, который внутренне вызовет конструктор. Таким образом, каждый раз, когда кто-то хочет экземпляр этого объекта, вы всегда будете возвращаться к нему, поэтому вы будете использовать память только для одного. Вам всегда нужен конструктор в объектно-ориентированном программировании на каждом языке OO. В java во многих других языках подразумевается конструктор по умолчанию объекта и создается автоматически. Но вам нужны некоторые пользовательские функции, которые вы должны сделать самостоятельно.
Вы видите несколько хороших примеров использования. Однако, если у вас есть что-то конкретное в своем уме, сообщите нам об этом. Я имею в виду, если у вас есть конкретный случай, когда вы не уверены, следует ли использовать статический метод или конструктор. Во всяком случае, вам определенно понадобится конструктор, но я не уверен в статическом методе.