В 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
был какой-то побочный эффект, который вы хотели вызвать.Но поскольку конструкторы обычно считают плохим стилем иметь какие-либо нетривиальные побочные эффекты (или, вообще говоря, делать что-то кроме установки нового объекта), у вас обычно не должно быть оправдания написанию такого кода.