Когда подходящее время использовать ключевое слово «new»? - PullRequest
9 голосов
/ 07 января 2012

Когда необходимо использовать ключевое слово new в Java.Я знаю, что вы должны использовать его при создании экземпляра объекта, подобного этому:

TextView textView = new TextView(this);

Иногда в коде я замечаю, что new не используется, и я запутываюсь .. В этой строкес кодом:

    AssetManager assetManager = getAssets();

Почему экземпляр AssetManager не создается следующим образом:

AssetManager assetManager = new AssetManager();

, тогда он устанавливается равным getAssests ()?

Когда следует использовать new

Спасибо!

Ответы [ 8 ]

11 голосов
/ 07 января 2012

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

если вы хотите более подробное описание нового посещения the oracle docs

Объекту понадобится ключевое слово 'new', если оно равно нулю (что не так инициализировано).

EDIT:

В текущих обстоятельствах это всегда будет печатать «нужно новое».

Object mObj = null;
if (mObj == null)
    System.out.println("needs new");
else
    System.out.println("does NOT need new");

OUTPUTS: needs new

Итак, чтобы исправить это, вы должны сделать что-то вроде:

Object mObj = new Object();
if (mObj == null)
    System.out.println("needs new");
else
    System.out.println("does NOT need new");
OUTPUTS: does NOT need new

И при таких обстоятельствах мы всегда увидим «НЕ НУЖНО»

6 голосов
/ 07 января 2012

В Java вы всегда должны использовать new для создания экземпляров объектов (ну, почти всегда).С getAssests() вы получаете уже созданный.Я предполагаю, что ваш вопрос возник из c ++, где new выделяет динамическую память, но поскольку в Java есть только динамические объекты, всегда требуется новое.

5 голосов
/ 29 октября 2017

В Java new MyClass() создает новый экземпляр из MyClass и возвращает ссылку на него.

Между тем объявление:

MyClass foo;

определяет переменную foo, которая может хранить ссылку на экземпляр MyClass, или специальное значение null, которое указывает на отсутствие такой ссылки.Если вы не указали ссылку на foo, ее значением по умолчанию будет null.

Вы, безусловно, можете комбинировать эти вещи, например, так:

MyClass foo;           // define a variable foo that can store an object reference
foo = new MyClass();   // create a new object and assign a reference to it to foo

или,аналогично, вот так:

MyClass foo = new MyClass();  // combined variable definition and assignment

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

MyClass foo, bar;      // define two reference variables, foo and bar
foo = new MyClass();   // create a new object and assign a reference to it to foo
bar = foo;             // now foo and bar point to the same object

или даже:

MyClass foo = new MyClass(), bar = foo;  // same, but shorter

Обратите внимание, что в Java, в отличие от некоторых других языков, таких как C ++, вы никогда не можете назначить (aкопия) фактического объекта в переменную.Скорее, Java-объекты всегда доступны через ссылки на них.Когда кто-то говорит о «назначении объекта переменной» или «передаче объекта в качестве параметра» или «возврате объекта из метода» в Java, на самом деле они всегда имеют в виду назначение, передачу или возврат ссылки к объекту.


Методы, которые ваш код вызывает (и часто делает), также возвращают ссылки на объекты.Например, если у вашего класса есть такой метод:

private MyClass getSomeObject() {
    // ...some code here...
}

, вы можете вызвать его и сохранить ссылку, которую он возвращает, в переменную, например:

MyClass foo;
foo = getSomeObject();

или вот так:

MyClass foo = getSomeObject();

Мы можем сказать из объявления метода, что getSomeObject() всегда будет возвращать ссылку на экземпляр MyClass (или null), но не там, где этот экземпляр на самом деле происходит.Это полностью зависит от того, что делает код внутри метода getSomeObject().Код может всегда создавать новый экземпляр MyClass с new MyClass() каждый раз, когда он вызывается, и возвращать ссылку на него, или он всегда может возвращать ссылку на тот же самый объект .Или, конечно, иногда он может возвращать ссылку на новый объект, а иногда и на ранее созданный.


Обратите внимание, что если вы назначаете новое значение переменной, какой бы переменной она ни содержаласьпрежде чем будут забыты.Если забытое значение окажется последней ссылкой на некоторый объект, то этот объект сам будет уничтожен сборщиком мусора Java.

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

MyClass foo = new MyClass();  // create a new object and assign (a reference to) it to foo
foo = getSomeObject();        // forget the previous content of foo and replace it with whatever getSomeObject() returns

, что обычно не имеет смысла, так как вы будете создавать новый экземпляр MyClass просто для того, чтобы сразу отбросить вашу единственную ссылку на него и заменить ее чем-то другим.По сути, приведенный выше код в точности эквивалентен следующему:

new MyClass();       // create a new object and throw away(!) the reference to it
MyClass foo = getSomeObject();  // assign whatever getSomeObject() returns to foo

Единственный момент, который может иметь смысл даже удаленно, был бы, если бы вы хотели создать новый экземпляр MyClass и немедленнопусть это будет сборщик мусора, например, потому что у конструктора MyClass был какой-то побочный эффект, который вы хотели вызвать.Но поскольку конструкторы обычно считают плохим стилем иметь какие-либо нетривиальные побочные эффекты (или, вообще говоря, делать что-то кроме установки нового объекта), у вас обычно не должно быть оправдания написанию такого кода.

3 голосов
/ 07 января 2012

new всегда используется для создания нового объекта.

this

AssetManager assetManager = getAssets();

- это просто присвоение значения, возвращенного методом getAssets(), для ссылки assetManager.

[править]

Я солгал о new, можно сделать что-то вроде этого:

Foo.class.newInstance();

, а также вы можете использовать отражение:

Foo.class.getDeclaredConstructors(Class[] parameterTypes).newInstance(arguments);
3 голосов
/ 07 января 2012

Новое используется, когда вы вызываете конструктор для функции. getAssets () возвращает AssetManager, ему не нужно создавать новый.

2 голосов
/ 07 января 2012

Поскольку вы отметили это с помощью [android], я предполагаю, что ваш код находится внутри Activity или Service.В этом случае getAssets() - это метод класса, который вы расширяете.Таким образом, вы на самом деле не создаете его, а просите существующий код дать вам ссылку на то, что уже существует.

2 голосов
/ 07 января 2012

Используя new, вы выделяете память для объекта.

Использование getXXX() используется для получения существующего объекта, который уже выделен.

0 голосов
/ 07 января 2012

обратите внимание на заглавную букву в TextView и ее отсутствие в getAssets.getAssets не является классом, подобным TextView, это метод, возвращающий объект.И, как и многие другие, упомянутые, ваш актив уже существует.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...