• 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:
  • Campbell Ritchie
  • Tim Cooke
  • Liutauras Vilda
  • Jeanne Boyarsky
  • paul wheaton
Sheriffs:
  • Ron McLeod
  • Devaka Cooray
  • Henry Wong
Saloon Keepers:
  • Tim Holloway
  • Stephan van Hulst
  • Carey Brown
  • Tim Moores
  • Mikalai Zaikin
Bartenders:
  • Frits Walraven

records. If the first line is a call to another ctor, then how can you set a field on that line also

 
Ranch Hand
Posts: 662
3
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Boyarsky-Selikoff Sybex829 Ch 7 page 380

I don't understand what this means. If the first line is a call to another ctor, then how can you set a field on that line also?

you can only transform the data on the first line. After the first line, all of the fields will already be assigned


from

The first line of an overloaded constructor must be an explicit call to another constructor via this(). If there are no other constructors, the long constructor must be called. Contrast this with what you learned about in Chapter 6, where calling super() or this() was often optional in constructor declarations. Also, unlike compact constructors, you can only transform the data on the first line. After the first line, all of the fields will already be assigned, and the object is immutable.






 
Ranch Hand
Posts: 79
3
  • Likes 2
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I found it confusing too.
The first line means the call to another constructor. So whatever needs to be done to the parameters, it must happen when the other constructor is called. The chain of constructors will end up with the canonical constructor and the record's data will be set final at that point. When you return from the call to the other constructor, the fields will be set and will be final/immutable. So you can't do anything after the call to that constructor which happened on the first line.
 
Marshal
Posts: 79956
396
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Please avoid abbreviations like “ctor” which can confuse people; Google translate can't understand it.

IG has told you, fields in a record are implicitly final, and your line 4 is trying to assign a final variable twice. I suggest you go through the JLS about records and see what it says about multiple constructors. What Boyarsky and Selikoff wrote is by no means clear, but the only way to avoid double assignments is to restrict all constructors but one to calling this(...); and nothing else. Mutable classes allow assignments to follow this(...); and you doubtless already know why you mustn't omit assigning of any fields in every record constructor.
 
Anil Philip
Ranch Hand
Posts: 662
3
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Ira Go wrote:I found it confusing too.
The first line means the call to another constructor. So whatever needs to be done to the parameters, it must happen when the other constructor is called. The chain of constructors will end up with the canonical constructor and the record's data will be set final at that point. When you return from the call to the other constructor, the fields will be set and will be final/immutable. So you can't do anything after the call to that constructor which happened on the first line.



Then you might as well have just one compact constructor!
 
Anil Philip
Ranch Hand
Posts: 662
3
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Campbell Ritchie wrote:Please avoid abbreviations like “ctor” ...
IG has told you,



Haha you used an abbreviation here
 
Master Rancher
Posts: 5060
81
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Anil Philip wrote:If the first line is a call to another ctor, then how can you set a field on that line also?

you can only transform the data on the first line. After the first line, all of the fields will already be assigned


That call to the other constructor is how the fields are being set.  Running the other constructor sets the fields.

But while the first line must be a call to another constructor, there are nonetheless ways to insert some transformation of the data before the constructor is called.  You show one yourself:

Here the first line of the Crane(int, String) constructor is an invocation of the canonical constructor - and yet, it is changing the data on the way.  It's replacing numberEggs with numberEggs + 1.  And it's putting firstName and lastName together into a single name, separated by " ".  Those are both transformations of data, made by inserting simple expressions into the constructor invocation.  You could also insert an arbitrarily complex expression into that first line - but at some point, it's better to create a new static method, and insert that instead:

So you can squeeze quite a bit of transformation into that one line, if you need to.  Note that you aren't allowed to invoke an instance method there, or a this reference, because the current instance isn't fully constructed yet.  But you can do a lot of other things with the constructor parameters.

Anil Philip wrote:Then you might as well have just one compact constructor!


A compact constructor is a more flexible way to handle this sort of initialization.  But you can only have one compact constructor, and it is a direct companion to the one canonical constructor - that is, you can only reference variables from the canonical constructor arguments, and the canonical constructor is implicitly called at the end of the compact constructor.  The point being, all of this is of no help if you want to be able to create a constructor with a different list of arguments.  For that you need an overloaded constructor, by definition.  And that's when you have to deal with the no-data-alteration-except-on-first-line rule.

Note that they are finding ways to relax these rules in future versions of Java, starting with JDK 22.  But for now, these are the rules we must deal with.
 
Time flies like an arrow. Fruit flies like a banana. Steve flies like a tiny ad:
Gift giving made easy with the permaculture playing cards
https://coderanch.com/t/777758/Gift-giving-easy-permaculture-playing
reply
    Bookmark Topic Watch Topic
  • New Topic