• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Tim Cooke
  • Campbell Ritchie
  • paul wheaton
  • Ron McLeod
  • Devaka Cooray
Sheriffs:
  • Jeanne Boyarsky
  • Liutauras Vilda
  • Paul Clapham
Saloon Keepers:
  • Tim Holloway
  • Carey Brown
  • Piet Souris
Bartenders:

Lost and confused, p. 129 (K&B7)

 
Sheriff
Posts: 11606
178
Hibernate jQuery Eclipse IDE Spring MySQL Database AngularJS Tomcat Server Chrome Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Mark Kevin wrote:That's not correct. The first bullet on page 152 proves it. "A constructor is always invoked when a new object is created." You're splitting non-existent hairs. When you create an object you invoke a constructor in these circumstances; they are inseparable.


It depends on the interpretation of the word "invoke".

Of course I know that constructors are required to be executed to create a new object. I even know that when a constructor is called, there will be a whole chain of constructors being called, all the way back to the constructor of Object. I also know that you require to invoke the new operator followed by a call to the constructor to create an object. But I also know that if you want to invoke a constructor like you would invoke a method (e.g. to pass some default parameters to an overloaded or parent constructor), you can do this only from within another constructor.
 
Ranch Hand
Posts: 67
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Although that's a good attempt, I don't think it fits well for a bullet list notation where statements are mostly concise and to the point.



I agree with that, completely. But length doesn't make it wrong, especially since most of it was written by you or the book:

"The only way a constructor can be invoked is from within another constructor (using a call to super() or this()), or from within static or instance methods, static or instance initializer blocks, or even constructors, if the call to the constructor is preceded by the keyword 'new'." Trying to invoke a constructor like you would invoke a method (using only its name) is not allowed."





 
Roel De Nijs
Sheriff
Posts: 11606
178
Hibernate jQuery Eclipse IDE Spring MySQL Database AngularJS Tomcat Server Chrome Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Mark Kevin wrote:False logic. Incomplete is not necessarily incorrect.


That's true! But not in this case. Let's say we add that suggestion into the book in the second edition, it's likely people will complain about that statement being incorrect because it states you can only invoke a constructor from within a method with the call to the constructor preceded by the keyword new. And then they illustrate it with perfectly valid examples using a static initializer block, a static initializer expression, a constructor, and so on.

Mark Kevin wrote:That would be like saying a person is from Brussels, but because you didn't mention he was also from Belgium he's not from Belgium.


Indeed, he could be from Wisconsin as well
 
Mark Kevin
Ranch Hand
Posts: 67
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator




The suggestion you made was incomplete and thus incorrect.




(I made a mistake. Let me rephrase that).
False logic. Incomplete is not necessarily incorrect. That would be like saying a person is from Brussels, but because you didn't mention he was also from Belgium he's not from Brussels.
 
Roel De Nijs
Sheriff
Posts: 11606
178
Hibernate jQuery Eclipse IDE Spring MySQL Database AngularJS Tomcat Server Chrome Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Mark Kevin wrote:(I made a mistake. Let me rephrase that).
False logic. Incomplete is not necessarily incorrect. That would be like saying a person is from Brussels, but because you didn't mention he was also from Belgium he's not from Brussels.


In that particular case, incomplete is indeed not incorrect. But with that statement it definitely is (as I explained in my previous post).
 
Mark Kevin
Ranch Hand
Posts: 67
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator


Hey, I just got promoted to Ranch Hand. Thanks, Roel.

It depends on the interpretation of the word "invoke".



According to your book, and your very own words, which I pointed out above twice, a call in main() with the call to the constructor preceded by the word 'new' invokes the constructor. I'll type it again: "A constructor is always invoked when a new object is created." (p. 152)


But I also know that if you want to invoke a constructor like you would invoke a method (e.g. to pass some default parameters to an overloaded or parent constructor), you can do this only from within another constructor.



First, I think it also applies to no-argument constructor calls regardless of parameters, but that's not the main issue. And it's more about using the word 'new'.

Secondly, you're trying to rewrite the bullet. It doesn't say, and it can't even be reasonably implied, that the statement is limited to situations where you invoke a constructor "like you would invoke a method." The bullet is a very concrete, albeit misleading, statement. "The only way a constructor can be invoked is from within another constructor."

Here's an idea. Maybe it would be clearer if it said, "Where the call to the constructor is not preceded by the keyword 'new', the only way a constructor can be invoked is from within another constructor using this() or super() as the first statement."

What do you think?





 
Mark Kevin
Ranch Hand
Posts: 67
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator



it's likely people will complain about that statement being incorrect because it states you can only invoke a constructor from within a method with the call to the constructor preceded by the keyword new.



That's not what the statement says; you are mis-characterizing that. It doesn't say, "you can only invoke a constructor from within a method." Where did you get that from? It offers additional ("or") alternatives to constructor invocations. If you want to expand those other options, well, those can be added as well. You are working against your own argument because the bullet is narrowly stated ("the only way").
 
Roel De Nijs
Sheriff
Posts: 11606
178
Hibernate jQuery Eclipse IDE Spring MySQL Database AngularJS Tomcat Server Chrome Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Mark Kevin wrote:Where did you get that from? It offers additional ("or") alternatives to constructor invocations. If you want to expand those other options, well, those can be added as well. You are working against your own argument because the bullet is narrowly stated ("the only way").


That's my interpretation of the statement "The only way a constructor can be invoked is from within another constructor (using a call to super() or this()), or from within a method with the call to the constructor preceded by the keyword 'new'." and I think many others will have the same interpretation. There's no suggestion at all in that statement (because it ends with a dot) that "from within a method" is not the only thing you can do if you call the constructor preceded by the new operator. So either call constructor from within another constructor (using this/super) or call constructor preced by new from within a method. These are the only 2 options I can see (based on that statement).
 
Roel De Nijs
Sheriff
Posts: 11606
178
Hibernate jQuery Eclipse IDE Spring MySQL Database AngularJS Tomcat Server Chrome Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Mark Kevin wrote:According to your book


I wish it was my book

Mark Kevin wrote:Here's an idea. Maybe it would be clearer if it said, "Where the call to the constructor is not preceded by the keyword 'new', the only way a constructor can be invoked is from within another constructor using this() or super() as the first statement."

What do you think?


Definitely better than the previous one (as it's more concise and still correct) But half of the statement (or even slightly more) is almost a copy of the second bullet point of that page (about each constructor having this() or super() as the first statement). And also wondering if the accompanying code snippet should not be changed as well.

Like I said in one of the other posts: based on that code snippet, I think the authors just want to emphasize you can't invoke the constructor by just using its name (like you would invoke a method). And thus that first sentence should be replaced with something like "Trying to invoke a constructor like you would invoke a method (using only its name) is not allowed". The part about this() or super() is already mentioned in the 2nd bullet point.

If that bullet point was actually about invoking the constructor from within a constructor (using this() or super()), I would have expected a code snippet like
 
Mark Kevin
Ranch Hand
Posts: 67
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator


There's no suggestion at all in that statement (because it ends with a dot) that "from within a method" is not the only thing you can do if you call the constructor preceded by the new operator. So either call constructor from within another constructor (using this/super) or call constructor preced by new from within a method. These are the only 2 options I can see (based on that statement).



You continue proving my point and ignoring the bullet which states the "only" way a constructor can be invoked. Now you agree with me. It's not the only way. In fact, I've been getting second opinions by some, apparently, knowledgeable Java programmers who agree that the bulleted statement is false. On its face the reference to "only" is too narrow, and you just conceded that. Actually, according to Oracle, there are at least three ways to invoke a constructor.

Instead of arguing about a point we agree on, since you now agree that the bullet is false as written, we should try to fix it so others aren't mislead as I was.
 
Mark Kevin
Ranch Hand
Posts: 67
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Definitely better than the previous one (as it's more concise and still correct) But half of the statement (or even slightly more) is almost a copy of the second bullet point of that page (about each constructor having this() or super() as the first statement). And also wondering if the accompanying code snippet should not be changed as well.

Like I said in one of the other posts: based on that code snippet, I think the authors just want to emphasize you can't invoke the constructor by just using its name (like you would invoke a method). And thus that first sentence should be replaced with something like "Trying to invoke a constructor like you would invoke a method (using only its name) is not allowed". The part about this() or super() is already mentioned in the 2nd bullet point.



I don't think mentioning the calls to this() and super() is a problem, and should be included for clarity, because I read the second bullet on that page as focused on what the first statement in each constructor is; it focuses on the first statement only. Here we're talking about the call to the constructor initially. Also, a reference to super() and this() is not misplaced in what I wrote because the last bullet on page 152 mentions it, stating, "A constructor can be directly invoked only by another constructor (using a call to super() or this())." I just copied that part for purposes of clarity so we're okay there. (the issue is "only" and "another constructor")

Note, if you make any changes to the one bullet it will have to be changed here as well on page 152.

Getting the wording right is not easy. Because there are at least three ways a constructor can be invoked, not just the one, and because a constructor can also be invoked by a method if using new, I find that bullet language is just too narrow, just too limited. I understand now what they were attempting to convey, but that added code, while illustrative seems to confuse that crystal clear statement preceding it. I'm not the only one confused by that statement. Other people scratch their heads as well, not here, but elsewhere, and some come right out and say it's flatly not true. Of course I didn't add the code to that statement when I showed it around, which might have helped them, but again, it's too much work trying to reconcile conflicting things, the statement and the code.

I wrestled with it. I understand the accompanying code, but the preceding sentence didn't conform to that code or what I knew of calls to constructors.

All we're talking about here is changing a few words, adding a few. Nothing big. I can't believe I'm spending this much time on this when I could be flipping through index cards.

As far as the original code snippet in the book, it seems fine as is, but what do I know. I'm just glad I'm not in Paris.

Here's another can of worms. The last bullet page 152 says "directly" invoked. Maybe the authors imply a distinction between directly invoked and indirectly (such as using new in a method). But I would argue that even constructors with this() as the first statement usually are called somewhere by a call to the constructor with the preceding word 'new'. If so, that could have been clearer.






 
Roel De Nijs
Sheriff
Posts: 11606
178
Hibernate jQuery Eclipse IDE Spring MySQL Database AngularJS Tomcat Server Chrome Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Mark Kevin wrote:You continue proving my point and ignoring the bullet which states the "only" way a constructor can be invoked. Now you agree with me. It's not the only way.


Hold your horses! I didn't change my opinion about the original statement. For me it is still correct as it currently stands, no changes needed. The only way you can call a constructor is from within another constructor (using super() or this()). And I agree as well that you can use new to create a new object/instance and, as part of the whole object-creating process, constructors will be called and executed (just like missing classes will be loaded and initialized, instance variables will get a default value and so on), but you can not call the constructor directly. If you want to call a constructor directly, it can only be done from within another constructor.

Mark Kevin wrote:In fact, I've been getting second opinions by some, apparently, knowledgeable Java programmers who agree that the bulleted statement is false.


So those knowledgeable Java programmers seem to be an SO question. Always BeForthrightWhenCrossPostingToOtherSites. Thanks!

Mark Kevin wrote:Instead of arguing about a point we agree on, since you now agree that the bullet is false as written, we should try to fix it so others aren't mislead as I was.


I have been a moderator on this forum for quite some time now and I think I can honestly say I'm pretty active in this forum. As far as I can remember you are the first person who seems to have an issue with this bullet point. And I have seen many, many ranchers post doubts/confusion/questions about statements, paragraphs, and so on in K&B7 and other study guides as well. So I think you are probably one of the (very) few people having a problem understanding the statement. Maybe because you are reading into that statement? And reading into questions is definitely something you shouldn't do on mock exams and the actual exam, because that will probably result in wrong answers. In the (mock) exam questions it's very important to be aware of the "context of the question". In this thread you'll find a nice discussion about this "context of a question", it's definitely worth reading.
Finally, if I use the search engine of this website, I only find three threads about this statement: here, here, and here. And on both occasions different ranchers give the same explanation (about this() and super()).
 
Enthuware Software Support
Posts: 4906
60
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Roel De Nijs wrote:...but you can not call the constructor directly. If you want to call a constructor directly, it can only be done from within another constructor.


The fact that you have to make use of the words "call" and "directly" to explain what "invoked" in the original sentence is intended for, implies that the statement is ambiguous and should be improved. I know that from the context the implication that "invoked" is used to mean "call directly" is more plausible but that does not help a new programmer.

Btw, someone mentioned somewhere above that a constructor is always "invoked" when creating an object. I just want to mention an exception to this rule that this is not the case when you deserialize an object. This topic is not on the exam but one should at least know that such an exception exists to avoid being blindsided during an interview.
 
Roel De Nijs
Sheriff
Posts: 11606
178
Hibernate jQuery Eclipse IDE Spring MySQL Database AngularJS Tomcat Server Chrome Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Paul Anilprem wrote:I know that from the context the implication that "invoked" is used to mean "call directly" is more plausible but that does not help a new programmer.


I'll add an errata item to the overview to add the word "directly" to that sentence (cf. last bullet point on page 152 of the Two-Minute Drill).
 
Mark Kevin
Ranch Hand
Posts: 67
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator


If you want to call a constructor directly, it can only be done from within another constructor.



That's not necessarily true, either, come to think about it. Look at this piece of code:




Calling B() invokes this(), but what does this() invoke? It invokes B() which is not "another" constructor. Invoking B() with B bObject = new B(); executes this() which invokes the same no-argument constructor, B(). It's not another constructor but the same constructor, twice. The word "another" also needs to be removed and just call it "a constructor." The word "another" implies two different constructors.







 
Mark Kevin
Ranch Hand
Posts: 67
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Adding the code snippet with the accompanying sentence actually bolsters my argument and illustrates the conundrum.

This is how I see the problem. The code snippet and the sentence are not complimentary. They are opposed to each other. If the point of the bullet is the idea illustrated by the snippet, then the sentence doesn't illustrate it. If the point is the sentence, then the snippet doesn't support that sentence. I think they want to emphasize the lesson from the code snippet. An argument can be made that the bullet should be broken up into two bullets. Let's look at the bullet again.

The only way a constructor can be invoked is from within another constructor. In other words, you can't write code that actually calls a constructor as follows:



If they mean to say, "You can't call a constructor directly without preceding the call with 'new', then they should say it, and perhaps clarify the distinction between a direct and in-direct call - not everyone agrees on that definition.

But that doesn't fix the first sentence which is talking about something else entirely. First, we know that it's not the "only" way a constructor can be invoked. That has to go. Secondly, as we know it can be invoked from within the same constructor (using this()), the word "another" is false and should be removed.

Assuming it is clear that the word "direct" means "not using the word 'new', then it is more accurate to say, "A constructor can be invoked directly from within a constructor using this() or super()."

This approach avoids all of the ambiguity and confusion about things like, what does it mean to invoke? What is the difference between direct and indirect invocation? If a constructor invokes itself is that other constructor considered another constructor? (of course not). Is it really the only way to invoke a constructor when Oracle says you can invoke a constructor using new.

Is merely adding the word "direct" enough to overcome all of the other inconsistencies? I don't think so, but it is a good improvement.

Here is one possibility, using two bullets instead of one convoluted bullet.

Bullet 1) "A constructor can be invoked directly from within a constructor using this() or super()."

Bullet 2) "You cannot call a constructor directly from within a method."
(Assuming it's clear that the word directly means "without preceding the call to the constructor with 'new'".)




versus





 
Mark Kevin
Ranch Hand
Posts: 67
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

So those knowledgeable Java programmers seem to be an SO question. Always BeForthrightWhenCrossPostingToOtherSites. Thanks!



I'm not offended that you are accusing me of being dishonest. I'm the one who posted the question to get other opinions. There's nothing wrong with that.

Besides, it's not a cross-post. I was simply asking a question.





 
Roel De Nijs
Sheriff
Posts: 11606
178
Hibernate jQuery Eclipse IDE Spring MySQL Database AngularJS Tomcat Server Chrome Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Mark Kevin wrote:Calling B() invokes this(), but what does this() invoke? It invokes B() which is not "another" constructor. Invoking B() with B bObject = new B(); executes this() which invokes the same no-argument constructor, B(). It's not another constructor but the same constructor, twice. The word "another" also needs to be removed and just call it "a constructor." The word "another" implies two different constructors.


Let's focus only on code which compiles successfully! Your code snippet does not compile, because it has a recursive constructor invocation. That's not allowed and will give you a compiler error. So the word "another" is absolutely spot-on! And the compiler is a smart cookie and will detect this one as well
 
Roel De Nijs
Sheriff
Posts: 11606
178
Hibernate jQuery Eclipse IDE Spring MySQL Database AngularJS Tomcat Server Chrome Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Mark Kevin wrote:Bullet 1) "A constructor can be invoked directly from within a constructor using this() or super()."


If this bullet point should be added to the list, I would do a copy/paste of the last bullet point on page 152: "A constructor can be directly invoked only by another constructor (using a call to super() or this())".

Mark Kevin wrote:Bullet 2) "You cannot call a constructor directly from within a method."
(Assuming it's clear that the word directly means "without preceding the call to the constructor with 'new'".)


So that's actually what I already suggested some days ago albeit with a different wording.

 
Roel De Nijs
Sheriff
Posts: 11606
178
Hibernate jQuery Eclipse IDE Spring MySQL Database AngularJS Tomcat Server Chrome Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Mark Kevin wrote:I'm not offended that you are accusing me of being dishonest. I'm the one who posted the question to get other opinions. There's nothing wrong with that.


Luckily! Because it was not my intention to make you feel offended. It had been nice if you have mentioned "I posted a question about that statement here to get some different opinions" instead of "I've been getting second opinions by some, apparently, knowledgeable Java programmers who agree that the bulleted statement is false". If nothing's wrong with it, why not just come clean?
 
reply
    Bookmark Topic Watch Topic
  • New Topic