• Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Review Questions #20 in chapter 4, on page 226 (Java OCA 8 Programmer I Study Guide)

 
Mushfiq Mammadov
Ranch Hand
Posts: 187
25
Java jQuery Netbeans IDE
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Review Questions #20 in chapter 4 is:



If we insert this(2); to LINE 1 the code print 2, but it doesn't print 2 when we insert new BirdSeed(2); . new BirdSeed(2); can print 2 if numberBags is static. It is clear that new BirdSeed(2); is other object, really we refer to first object reference (seed.numberBags). But this(2); can print 2. It is unclear for me what is difference between this(2); and new BirdSeed(2); in this example?
 
Guillermo Ishi
Ranch Hand
Posts: 789
C++ Linux Python
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I think the problem with new BirdSeed(2) is it creates a new object, not the same object as the original caller. The reason it works if the variable is static is because there is only one copy of a static variable, shared between all instances.

I think BirdSeed(2) (without new) doesn't compile though. I think the problem is you just can't call a constructor that way.

line 1 line 2 doesn't matter. Boolean variable call doesn't matter
 
Roel De Nijs
Sheriff
Posts: 10662
144
AngularJS Chrome Eclipse IDE Hibernate Java jQuery MySQL Database Spring Tomcat Server
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Mushfiq Mammadov wrote:It is unclear for me what is difference between this(2); and new BirdSeed(2); in this example?

Let's focus first on A and B. BirdSeed(2); is an invalid constructor invocation, but it's a valid method invocation of the BirdSeed method (which happens to be exactly the same as the class name and thus the constructors). Unfortunately the method BirdSeed does not exist in the BirdSeed class, so this code does not compile. That's why answers A and B are wrong!
If you add the following method BirdSeed to the BirdSeed class, the code will still compile and thus the compiler can differentiate between constructor BirdSeed (no return type) and the method BirdSeed (that's why a method must have a return type; even if there's no return value, we use void)Both answer A and B would be correct!

Now we have a look at C and D. new BirdSeed(2); is a valid constructor invocation and this invocation creates another BirdSeed object. So if you call the no-arg constructor of BirdSeed, 2 BirdSeed objects will be created: one through the invocation of the no-arg constructor (the this object and the object which will be referred by the reference variable seed) and another BirdSeed object through the invocation of the 1-arg constructor (this object is not referred by any reference variable, so it's immediately eligible for GC). This "temporary" object's numberBags will be 2, but the numberBags field of the "this" object (referred by reference variable seed) will still have its default value (0). This can easily be demonstrated with the following codeOutput:
this BirdSeed@3e0a765c 0
temp BirdSeed@20e0b1d6 2
seed BirdSeed@3e0a765c 0

So as explained before the reference variable seed refers to the "this" object (that's the object created by invoking the no-arg constructor). The object created by the 1-arg constructor (and here referred by reference variable temp is different, it has a different hash code).
It doesn't make a difference if new BirdSeed(2); is added on line1 or line2, both invocation will create another object which is immediately eligible for GC but won't affect the numberBags property of the "this" object. So both answers C and D are wrong!

Finally we have a look at E and F. As you should know, this(2); is a valid invocation of another constructor of the "this" object. That means using this() you could invoke any constructor from the same class (using super() you could invoke a constructor from the parent class). And you'll end up with just 1 object, the "this" object (the one the reference variable seed refers to). So this() is often used to invoke another constructor of the class with some default parameters. More info about using this with a constructor can be found here (with a few examples).
So let's say you have 2 constructors: a constructor with 1 parameter to provide the number of bags and a constructor without parameters which should always use 5 bags. This can be implemented with one of these two alternatives.
1/ without using this2/ using this
So using this(2); will initialize the numberBags property of the "this" object (referred by reference variable seed) to 2 and thus 2 will be printed. So you would think E and F to be the correct answers, but there's a catch! The call to another constructor using this() must be the very first statement of the constructor! That's why only answer E is correct and answer F is wrong. Let's illustrate with a similar code example:Output:
this BirdSeed@4b5d7792 2
seed BirdSeed@4b5d7792 2

So no 2nd object created when you use this to invoke another constructor of the same class. And this code (representing answer F) fails to compile

Hope it helps!
Kind regards,
Roel
 
Roel De Nijs
Sheriff
Posts: 10662
144
AngularJS Chrome Eclipse IDE Hibernate Java jQuery MySQL Database Spring Tomcat Server
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Guillermo Ishi wrote:line 1 line 2 doesn't matter.

If you are referring to the correct answer, that's wrong! line1 or line2 definitely matters: this(2); on line1 compiles successfully and this(2); on line2 fails to compile.
 
Roel De Nijs
Sheriff
Posts: 10662
144
AngularJS Chrome Eclipse IDE Hibernate Java jQuery MySQL Database Spring Tomcat Server
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Mushfiq Mammadov wrote:new BirdSeed(2); can print 2 if numberBags is static.

That's true as well! Because if numberBags is static, there's only 1 numberBags variable which is shared by all instances of the BirdSeed class. Illustrated once more with a code snippetOutput:
this BirdSeed@4b5d7792 2
temp BirdSeed@655538e5 2
seed BirdSeed@4b5d7792 2


Hope it helps!
Kind regards,
Roel
 
Guillermo Ishi
Ranch Hand
Posts: 789
C++ Linux Python
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Roel De Nijs wrote:
Guillermo Ishi wrote:line 1 line 2 doesn't matter.

If you are referring to the correct answer, that's wrong! line1 or line2 definitely matters: this(2); on line1 compiles successfully and this(2); on line2 fails to compile.

Yep, you are right. this() or super() has to be the first line. If you'd asked me that, no problem. But I didn't notice it in the code. That's why I hate this test.
 
Mushfiq Mammadov
Ranch Hand
Posts: 187
25
Java jQuery Netbeans IDE
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Roel De Nijs wrote: So let's say you have 2 constructors: a constructor with 1 parameter to provide the number of bags and a constructor without parameters which should always use 5 bags. This can be implemented with one of these two alternatives.
1/ without using this2/ using this
So using this(2); will initialize the numberBags property of the "this" object (referred by reference variable seed) to 2 and thus 2 will be printed.


That is what I want to know, this(5); -> this.numberBags = 5; Perfect explanation Thanks a lot, Roel!
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic