I've recently started learning about Static Blocks and Instance Initializers. I wrote this program that tries the two concepts out. As I understand it, static blocks are blocks of code between curly brackets in a class marked by the keyword "static". They are executed once and only once when the class is loaded (this apparently was not always true for previous versions, but is fixed in 1.4). Instance Initializers are blocks of code between curly brackets (without the keyword "static"). They are executed every time the class is instantiated before the constructor is called. These can be used to initialize an anonymous class-- anonymous classes can't have a constructor, as they have no name.
One thing which is a bit odd is that it *looks* like the instance initializers are being called before the constructors, but this is not the case-- I read up on the order in which these events happen: 1. Memory for the object is allocated on the heap. 2. That memory is cleared, setting data fields to be set to zero, 0.0, null, etc. 3. The class constructor is called. 4. The parent classes constructors are called recursively. 5. Explicit initializers in the constructor are called, and any Instance Initializers are called. 6. The rest of the statements in the class constructor are called. The code for printing messages from the constructors falls into step 6, so it finishes after the Instance Initializers are called. Does this all seem correct? Do they usually ask about things like this on the certification exam? Thanks in advance. -- Zeno (This post comes from related posts I originally started at http://www.javajunkies.org) [ April 10, 2003: Message edited by: Tim Allen ] [ April 10, 2003: Message edited by: Tim Allen ] Edited by Corey McGlone: Added Code Tags [ April 10, 2003: Message edited by: Corey McGlone ]
Unfortunately, the JLS is a little confusing about this point, but instance initializers are executed prior to the constructor. From the JLS, §12.5 Creation of New Class Instances, you go through these 5 steps when creating a new instance: 1. Assign the arguments for the constructor to newly created parameter variables for this constructor invocation. 2. If this constructor begins with an explicit constructor invocation of another constructor in the same class (using this), then evaluate the arguments and process that constructor invocation recursively using these same five steps. If that constructor invocation completes abruptly, then this procedure completes abruptly for the same reason; otherwise, continue with step 5. 3. This constructor does not begin with an explicit constructor invocation of another constructor in the same class (using this). If this constructor is for a class other than Object, then this constructor will begin with an explicit or implicit invocation of a superclass constructor (using super). Evaluate the arguments and process that superclass constructor invocation recursively using these same five steps. If that constructor invocation completes abruptly, then this procedure completes abruptly for the same reason. Otherwise, continue with step 4. 4. Execute the instance initializers and instance variable initializers for this class, assigning the values of instance variable initializers to the corresponding instance variables, in the left-to-right order in which they appear textually in the source code for the class. If execution of any of these initializers results in an exception, then no further initializers are processed and this procedure completes abruptly with that same exception. Otherwise, continue with step 5. (In some early implementations, the compiler incorrectly omitted the code to initialize a field if the field initializer expression was a constant expression whose value was equal to the default initialization value for its type.) 5. Execute the rest of the body of this constructor. If that execution completes abruptly, then this procedure completes abruptly for the same reason. Otherwise, this procedure completes normally. In the example:
In that section, the JLS (in step 3) starts talking about which constructor needs to be executed (going up the class hierarchy to Object). So, it would seem, from that, that the constructor is first invoked. However, if you look ahead to step 4, once we have the class that needs to be initialized, we leave the constructor in order to invoke the instance initializer and any instance variable initializers (in textual order). Once that's done, we then go on to step 5 and execute the constructor for the given class. Now that this class is done being initialized, we can go on to the next class (which would be the child of this class) until we have initialized the class that we originally said we wanted. Here's a simple example to show what I mean:
In this code, the instance initializer sets the variable num to 5, but the constrcutor sets it to 6. I then print out the final value of num after the object has been fully initialized. As num can only hold one value, the value that will be printed will be the result of the last statement that was executed. In this case, the last statement must have been the assignment within the constructor, proving that the instance initializer was invoked prior to the constructor. I hope that helps, Corey
Is there a resource that explains it in plain english?
Joined: Dec 20, 2001
Originally posted by Barkat Mardhani: Is there a resource that explains it in plain english?
Hmph. I thought I did a pretty good job. :roll: The JLS is always the best source, but it can be a bit confusing at times. Here is the order to things (I believe you can probably find this in most cert study texts, as well): 1. When the class is loaded, execute and static initializers and static variable initializers (in textual order) 2. When an instance of the class is created, follow these steps: 3. If the class has a superclass (all classes except Object do) that has not been initialized, repeat step 3 with the superclass. If not, go on to step 4. 4. Execute all instance initializers and instance variable initializers in textual order. 5. Execute the appropriate constructor. 6. Repeat steps 3-5 until initialization is complete.
That's how it works. (or is at least a pretty good summary) I hope that helps, Corey
Tim - (from the Department of focus ), FYI - while it's good stuff to know, it's not on the exam! -Bert
Spot false dilemmas now, ask me how!
(If you're not on the edge, you're taking up too much room.)
Timothy Chen Allen
Joined: Mar 16, 2003
Originally posted by Bert Bates: Tim - (from the Department of focus ), FYI - while it's good stuff to know, it's not on the exam! -Bert
Hi Bert, That's good to know! I was imagining some weird question about what happens first! Thanks to all for their responses. Though it's not on the exam, I do want to understand this (more out of some language-lawyer aspiration that I have than any useful reason), and the responses I've gotten (especially from Sherlock/Corey) have been extremely helpful.
Joined: Aug 05, 2002
Bert: Are you saying it is not on exam? Last year I was taking some mock exam from Dan's site. It included a question testing stuff discussed here. I do not know if scope has changed since.... Barkat
Joined: Dec 20, 2001
Originally posted by Barkat Mardhani: Bert: Are you saying it is not on exam? Last year I was taking some mock exam from Dan's site. It included a question testing stuff discussed here. I do not know if scope has changed since.... Barkat
Some of this material may appear on the exam. For example, constructors and initializers are on the exam, but you won't have to know intimate details about them. Just know what they are and that parent classes are initialized before child classes (it really only makes sense if they are). Corey
Joined: Oct 14, 2002
Tim and Barkat - To clarify: what's in the exam, and what's not: constructors - in static methods - in static variables - in static blocks - not initialization blocks - not The exam is always up for revision, but we'll all hear about that - this information is for the current exam only. :roll: -Bert