This week's book giveaway is in the OO, Patterns, UML and Refactoring forum. We're giving away four copies of Refactoring for Software Design Smells: Managing Technical Debt and have Girish Suryanarayana, Ganesh Samarthyam & Tushar Sharma on-line! See this thread for details.
I would say as a rule of thumb for beginners, initialise all your fields in the constructor. Make sure not to forget any, otherwise you may suffer a NullPointerException (or calculate an incorrect value for a primitive).
You may have good reasons for initialising fields outside the constructor, but look what is happening. Your Tomato class has the problem that its "quality" is always A. Do you never have any B tomatoes, or even C tomatoes, which are only useful to throw at people when you have had too much to drink? This is what I suggest:That has the problem that people can pass "Excellent" or "Hippopotamus" as qualities rather than A B C; you could avoid that drawback by having "quality" a member of an enum.
If you are going to initialise your fields with default values, you can do it like this . . . but I personally would still do it in the constructor
Ok the advantages of using a constructor vs. using explicit initialization vs. instance init block could be like such:
An instance constructor can take arguments and can be overloaded. This allows you to set the object state according to external input. That is something obviously you can't do when you use explicit initialization or an init block.
An explicit initialization is limited to simple assignments such as like what you did in your example: private String quality = "A"; You can't get too much more complex than that. You're limited to basically 1 line of code that results in the assignment.
An instance initialization block will let you execute multiple lines of code...try/catch exceptions, etc...and you can do complex calculations if necessary to arrive at your final value.
Additionally, keep in mind that the compiler copies instance init block code into all constructors...so this is a good way of sharing common initialization code between multiple constructors if you should need to do so. Here's some more explanation:
I don't think there's any real rule of thumb so to speak...just use whatever fits best for the given scenario once you make sure that you fully understand the pros and cons of each approach. Once you get the grasp of the concepts then it will become pretty evident to you which usage is best for given scenarios. And thanks for posting this question, by the way. It forced me to recall some basics about which I hadn't thought much lately and reminded me of potentially powerful techniques that I don't often use but are available nonetheless.
Joined: Oct 13, 2005
There is also the option of using factory methods, but that is rather beyond the "beginning" stage.