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

About contructor in java...

 
Greenhorn
Posts: 5
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi I have a philosophical/design question about constructor in java vs initialization of member variable... This is a basic question but I need to know the rational behind this for my personal culture! Let's begin with a little bit of code.

Given this class hierarchy:




And then this initialization:



Here the sequence of call:


With this code, Java will call the ArtistInABand() contructor before initializing the Guitarist.effectMap. When the Guitarist.setupYourInstrument() is called , the effectMap will be null...

Here comes the question: Why does java don't initialize member variables before calling the parent constructor?
NOTE: One advised developer will tell me: Don't call abstract method from the constructor... This is a workaround that prevents this kind of problem... This answer leave my question unresolved...

Thanks!
 
Marshal
Posts: 79177
377
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Welcome to JavaRanch

Whoever told you not to call . . . from the constructor was correct.
You have a class and it has fields, and you ought to initialise all the fields by the time the constructor has completed. The fields are all initialised in the constructor; you can therefore pass information to the constructor and that can set up the fields. If you need anything else, eg the EffectMap, that must be initialised before it can be used; the unitialised Map in the setUpInstrument method will cause an Exception.The setUpInstrument method is rather badly named in this instance; maybe addEffectsToMap would be better.
 
Pierre-Yves Langlois
Greenhorn
Posts: 5
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks Campbell for your answer... Your suggestion to put the map in the parent class is good idea that I did not see at start... But in my case, the "effectMap" cannot be generalized to all sub class:




The drummer has no effects to setup... So if the map attribute is in ArtistInABand, this attribute is useless for the drummer class so the design of ArtistInABand is not "fully generalized"... But anyway, if I explicitly initialize effectMap in the declaration of the class, I don't understand why this initialization is not done when java enters the Guitarist constructor rather than when it exits ArtistInABand constructor.

 
Campbell Ritchie
Marshal
Posts: 79177
377
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
If there are different functions in a Drummer, then a Drummer IS-NOT-A(n) ArtistInABand. This is obviously ridiculous, so that would suggest there might be design problems with the ArtistInABand class.
Whoever told you not to . . . was correct. It is quite possible that your Drummer will have nothing to add to the Map, but every Musician will have a tuneMyInstrument() method. This should be abstract in Musician, and implemented as a final method in Violinist etc. Remember everybody has to set up or tune their instrument.
 
Pierre-Yves Langlois
Greenhorn
Posts: 5
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Ok your right... This design is flawed, I agree with that. Why should I need to call an abstract method in a constructor to force a specific method to be called if this method does specific stuff that could be done in the child constructor:



The abstract method setupInstrument is not needed at all. So ok for the design issue. And I will not call abstract method from a constructor But this leave my question unanswered... Why does the initialization of class attributes is done after the execution of the parent constructor and not before?
 
Pierre-Yves Langlois
Greenhorn
Posts: 5
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks Campbell for your time... I found a piece of the answer from the sun site... see section 12.5 Creation of New Class Instances


Unlike C++, the Java programming language does not specify altered rules for method dispatch during the creation of a new class instance. If methods are invoked that are overridden in subclasses in the object being initialized, then these overriding methods are used, even before the new object is completely initialized. Thus, compiling and running the example:

class Super {
Super() { printThree(); }
void printThree() { System.out.println("three"); }
}

class Test extends Super {
int three = (int)Math.PI;
// That is, 3
public static void main(String[] args) {
Test t = new Test();
t.printThree();
}
void printThree() { System.out.println(three); }
}

produces the output:

0
3

This shows that the invocation of printThree in the constructor for class Super does not invoke the definition of printThree in class Super, but rather invokes the overriding definition of printThree in class Test. This method therefore runs before the field initializers of Test have been executed, which is why the first value output is 0, the default value to which the field three of Test is initialized. The later invocation of printThree in method main invokes the same definition of printThree, but by that point the initializer for instance variable three has been executed, and so the value 3 is printed.



Why does Java does not initialize members like in C++... Maybe this question is too complex to be answered
 
Rancher
Posts: 600
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Why does Java does not initialize members like in C++... Maybe this question is too complex to be answered



It does, for instance variables. Primitives are default initialized to 0 (or false for booleans), while object references default to null.

John.
 
Campbell Ritchie
Marshal
Posts: 79177
377
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Pierre-Yves Langlois wrote:Why does Java does not initialize members like in C++... Maybe this question is too complex to be answered

No, that question is very simple. Java isn't C++.
 
Pierre-Yves Langlois
Greenhorn
Posts: 5
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
thanks!
 
Campbell Ritchie
Marshal
Posts: 79177
377
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
You're welcome
 
Don't get me started about those stupid light bulbs.
reply
    Bookmark Topic Watch Topic
  • New Topic