Я нашел блог, в котором предлагается избегать использования ключевого слова new при создание объекта класса. Вот несколько примеров создания объекта без ключевого слова new :

SampleObject obj = Class.forName("com.example.SampleObject").newInstance();

Или используя метод clone() -

SampleObject obj1 = new SampleObject();  
SampleObject obj2 = obj.clone();

Затем здесь у меня есть нашел несколько хороших примеров создания объекта без ключевого слова new

Я могу понять преимущества шаблона "Factory", избегая при этом ключевого слова new в основной части кода. Если я не использую какой-либо шаблон проектирования (для создания объектов), есть ли преимущества от создания объекта без ключевого слова new ? Или каковы причины создания объекта без new ?

5
Razib 19 Дек 2014 в 14:54
Я думаю, все дело в методе static для создания объектов. Что-то вроде Paths.get для стандартной библиотеки.
 – 
Dmitry Ginzburg
19 Дек 2014 в 14:56
Тогда как вы планируете создавать объект? Разве вы не собираетесь передавать строку для создания объекта, который вы будете использовать для загрузки своего класса?
 – 
SMA
19 Дек 2014 в 15:03

5 ответов

Лучший ответ

То, что вы читаете в блоге, должно быть, было посвящено фабричным методам и аналогичным методам, которые не избегают new, а скорее помещают их в более гибкий API.

У оператора new определенно нет общих недостатков. Он был и останется основным продуктом любого Java-кода и наиболее естественным способом создания объекта, в отличие от решения более общих задач, таких как «предоставьте мне точку входа в ваш API».

Все другие методы создания объектов без использования new являются инструментами специального назначения (клонирование, десериализация и т. Д.).

8
Marko Topolnik 19 Дек 2014 в 15:23
Другие методы должны быть менее эффективными, верно? Я имею в виду, что под капотом все они должны делать то, что new делает внутри. Я просматривал исходный код java newInstance0(), там много кода :). Обеспечивает ли какой-либо другой метод более высокую производительность, чем new?
 – 
TheLostMind
19 Дек 2014 в 15:47
Так как new является целью наиболее агрессивных оптимизаций со стороны среды выполнения, включая Escape Analysis с перспективой вообще не выделять объект, в принципе невозможно добиться большей эффективности, чем new. Как всегда, используйте стандартные идиомы и наслаждайтесь преимуществами оптимизирующего монстра, которым стал HotSpot.
 – 
Marko Topolnik
19 Дек 2014 в 15:49
На самом деле, вы могли бы стать более эффективными, чем новые... путем объединения экземпляров.
 – 
Andres
19 Дек 2014 в 16:23
Контекст «более эффективен при создании экземпляров».
 – 
Marko Topolnik
19 Дек 2014 в 16:24
Да, согласен. Тем не менее, я думаю, что заявление о том, что «у нового оператора определенно нет всеобъемлющих недостатков», немного вводит в заблуждение. Я видел много проблем, решаемых только заменой нового на что-то другое (синглетоны, DI, объединение и т. д.)
 – 
Andres
19 Дек 2014 в 16:27

Сложные объекты

В общем, вы можете избегать new для достаточно сложных объектов с нетривиальным созданием. Вы можете рассмотреть некоторые фабрики / строители, которые добавляют универсальности.

Например, если вы создаете большой составной объект, хорошо использовать шаблон построителя. (здесь длинный пример)

Простые объекты

Для простых объектов (наиболее частый случай) лучше всего использовать new.

Например, если у вас простой класс

public class Dog{
    private string name;

    //getter + setter
}

Тогда создание фабрики для этого будет излишним, и вы должны вызвать это через new Dog()

Внедрение зависимостей

В корпоративных приложениях вы обычно используете внедрение зависимостей, что позволяет вам явно избегать использования new. Вы не удалите все экземпляры объектов, но это дает хорошее улучшение. (Базовое руководство по Spring здесь)

2
Marcin Szymczak 19 Дек 2014 в 15:12
Дихотомия простой/сложный может быть не такой уж плодотворной. Многие очень простые объекты-значения поддерживаются фабриками запоминания.
 – 
Marko Topolnik
19 Дек 2014 в 15:02
1
Большинство правил дизайна не являются строгими. Вам нужно использовать здравый смысл, который создает исключения для них. Ты прав. Это не "полное руководство", а скорее руководство.
 – 
Marcin Szymczak
19 Дек 2014 в 15:05
Я уже подразумевал это в своем комментарии (когда использовал термин плодотворный).
 – 
Marko Topolnik
19 Дек 2014 в 15:18
Хороший. Тогда у нас одинаковое мнение :)
 – 
Marcin Szymczak
19 Дек 2014 в 15:22

Нет замены для new, даже Class.forName("XYZ").newInstance() ИМЕЕТ работать точно так же, как new, с той лишь разницей, что вы жестко кодируете весь класс (или даже package...class), следовательно, на самом деле достигается противоположность тому, что вы пытаетесь сделать, с new экземпляр может быть динамически разрешен и / или даже внедрен.

Если вы внедрите экземпляр interface A, вы вполне можете получить bean-компонент класса B, который реализует A - на самом деле он более динамичен и очень хорошо дополняет фабричные шаблоны. Это вряд ли возможно, если ваше имя класса жестко запрограммировано, по крайней мере, по моему скромному мнению.

1
specializt 19 Дек 2014 в 15:39
1
Когда вы используете Class.forName, вам не нужно жестко кодировать имя класса. ни пакет. Фактически, это основная причина использования Class.forName.
 – 
Andres
19 Дек 2014 в 16:20

Когда вы используете Class.forName, имя класса может быть установлено во время выполнения. Это может быть полезно для водителей, например.

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

Короче говоря, если вы хотите создать экземпляр определенного класса , new не причинит вреда.

Однако вы должны спросить себя:

  • Если вам действительно нужен новый экземпляр (в противном случае вам следует заменить new на синглтон или бассейн).
  • Если вы всегда будете использовать один и тот же класс для этого экземпляра (в противном случае вам следует заменить new на Dependency Инъекция или Factory Pattern).
1
Andres 19 Дек 2014 в 16:41

Если вам нравится вялый, медленный код, который сложно отлаживать, поддерживать и понимать, категорически избегайте использования ключевого слова new любой ценой, запутывайте его как можно больше!

-4
Dima 19 Дек 2014 в 15:06
3
Тссс! Не распространяйте правду о всех молодых «программистах» и «хакерах»! Им это не нравится!
 – 
specializt
19 Дек 2014 в 15:23
Для создания объектов, требующих внешних ресурсов, большего количества подкомпонентов ваш "незапутанный" код будет занимать 20 строк в каждом месте при создании объекта. Лучше иметь эти 20 строк в одном месте и не повторять их постоянно.
 – 
Marcin Szymczak
19 Дек 2014 в 15:24
1
Конечно, но это не устранит необходимость в new на вашем заводе.
 – 
specializt
19 Дек 2014 в 15:25
@MarcinSzymczak, а? Ставь 20 строк где хочешь... О чем ты?
 – 
Dima
19 Дек 2014 в 17:21