8

What exactly happens in Java when you instantiate the same object multiple times?

For example:

Test test = new Test();

then later on I will call it again, Test test = new Test(); again or inside a loop. Will the previous instantiation be disposed?

3 Answers 3

16
  1. each call new Test() creates a new object instance of the Test class
  2. test = new Test(); assigns a reference of that object to variable test
  3. A repeated statement test = new Test() creates a second instance of Test and assigns the reference it to the variable test again, so the first reference is replaced.

If and when the first instantiation will be disposed, however, depends. The Java runtime environment traces references, so as long as there are any references to an object in use, the object won't be disposed. For example, if between step 2 and step 3 the reference to the first instantiation is stored somewhere else (like Test test2 = test;), and that variable is still in scope when step 3 occurs, then the first object is not disposed, since test2 is still holding a reference to it. However, when there is no such statement and step 3 omits the one-and-only reference to the first object, then a dispose of that object will happen.

Note that the dispose itself does not happen immediately, but sometimes later, the next time when the garbage collector is run. But that is independent from the semantics of the code discussed, thats only a question of memory and performance.

4
  • 4
    The JVM does not do reference counting. Strictly speaking, the spec does not mandate how (or even that) garbage collection is implemented, but all mainstream JVMs use some sort of tracing collector. Aug 14, 2012 at 9:20
  • @MichaelBorgwardt: changed my answer due to your comment.
    – Doc Brown
    Aug 14, 2012 at 9:57
  • if between step 2 and step 3 the reference to the first instantiation is stored somewhere else (like Test test2 = test;), and that variable is still in scope when step 3 occurs... This is somewhat pedantic but garbage collection isn't based on scope, but on reachability. It's possible that a variable is in scope, but its value is no longer used, and that value can be garbage collected. Garbage collectors don't have scopes handy to make decisions based on that.
    – Doval
    Jan 3, 2017 at 19:04
  • @Doval: I agree, this comment is pedantic ;-)
    – Doc Brown
    Jan 3, 2017 at 19:25
5

1: Some wording: We don't instantiate objects at all, we instantiate classes, and the product of a class instantiation is an object (also called an instance). Of course we can instantiate a class as many times as required to create a new and different object with each instantiation.

2: Whatever, you cannot have the code you suggest:

Test test = new Test();
Test test = new Test();

neither you can have this:

for (i=0; i<3; i++) {
    Test test = new Test();
    Test test = new Test();
}

None will compile, because the part Test test is the declaration of variable test (of type Test), and no language, including Java, allows to declare twice the same variable in the same scope.

However you may assign multiple times the same variable (as the name implies), with different objects, like this:

Test test = new Test();
test = new Test();

The first line declares test and assign it an object newly created. The second line assign to test another object, also newly created.

Also note that shortcuts are allowed in Java:

for (i=0; i<3; i++) {
    Test test = new Test();
}

This loop will not declare test 3 times. It is understood as assigning three new different objects in sequence to the variable test which will be declared only once. (compare with the previous loop).

3: What happens to the variable test, and to the two objects of type Test?

The variable test is first assigned the reference of an object, then of another object. A variable retains only the last reference assigned.

The first object of type Test is not assigned to test anymore. If no other variable has been assigned its reference, then this object cannot be accessed in any way by the program, and thus is useless. It is made eligible to garbage collection by the system. At some point in time the system (the JVM) will run its garbage collector which will clear it from memory.

The second object will live as long as at least one variable references it, then the garbage collector will also take care of it and bring it to the Unreferenced Objects Cemetery. That's the true life of Java objects :-(

2
  • I happened to found that mistake in a class. The classs has a property declared as: WindowManager wm = new WindowsManager(); and then a method in which the programmer was using this property but mistakenly wrote: WindowManager wm = new WindowsManager(); again. It not only compiled, but also run!! No warning whatsoever and of course the application, which is a test, was not working well. Then I realized it was creating the object within the method scope and the property was never modified. So be careful Mar 16, 2016 at 16:49
  • 1
    As you perfectly explained this is not a re-assignation of the same variable. A similar shadowing mistake may occur when using a parameter if you forget the this keyword, like in constructors: this.name = name.
    – mins
    Jul 20, 2016 at 7:11
-1

Short answer: all previously created objects will be disposed of if no one points to them. Only the most recent one will exist because test references it.

Not the answer you're looking for? Browse other questions tagged or ask your own question.