When you learned about methods, you saw braces ({}). The code between the braces (some-times called “inside the braces”) is called a code block. Anywhere you see braces is a code block.
Sometimes code blocks are inside a method. These are run when the method is called. Other times, code blocks appear outside a method. These are called instance initializers. In Chapter 6, you learn how to use a static initializer.
How many blocks do you see in the following example? How many instance initializers do you see?
There are four code blocks in this example: a class definition, a method declaration, an inner block, and an instance initializer. Counting code blocks is easy: you just count the number of pairs of braces. If there aren’t the same number of open ({) and close (}) braces or they aren’t defined in the proper order, the code doesn’t compile. For example, you cannot use a closed brace (}) if there’s no corresponding open brace ({) that it matches written ear-lier in the code. In programming, this is referred to as the balanced parentheses problem, and it often comes up in job interview questions.
When you’re counting instance initializers, keep in mind that they cannot exist inside of a method. Line 5 is an instance initializer, with its braces outside a method. On the other hand, line 3 is not an instance initializer, as it is only called when the main() method is executed.
There is one additional set of braces on lines 1 and 6 that constitute the class declaration.
When writing code that initializes fields in multiple places, you have to keep track of the order of initialization. This is simply the order in which different methods, constructors, or blocks are called when an instance of the class is created. We add some more rules to the order of initialization in Chapter 6. In the meantime, you need to remember:
Fields and instance initializer blocks are run in the order in which they appear in the file.
The constructor runs after all fields and instance initializer blocks have run.
Let’s look at an example:
Running this example prints this:
setting field
setting constructor
Tiny
Let’s look at what’s happening here. We start with the main() method because that’s where Java starts execution. On line 9, we call the constructor of Chick. Java creates a new object. First it initializes name to “Fluffy” on line 2. Next it executes the println() state-ment in the instance initializer on line 3. Once all the fields and instance initializers have run, Java returns to the constructor. Line 5 changes the value of name to “Tiny”, and line 6 prints another statement. At this point, the constructor is done, and then the execution goes back to the println() statement on line 10.
Order matters for the fields and blocks of code. You can’t refer to a variable before it has been defined:
{ System.out.println(name); } // DOES NOT COMPILE private String name = “Fluffy”;
You should expect to see a question about initialization on the exam. Let’s try one more. What do you think this code prints out?
public class Egg {
public Egg() {
number = 5;
}
public static void main(String[] args) {
Egg egg = new Egg();
System.out.println(egg.number);
}
private int number = 3;
{ number = 4; } }
If you answered 5, you got it right. Fields and blocks are run first in order, setting number to 3 and then 4. Then the constructor runs, setting number to 5. You see a lot more rules and examples covering order of initialization in Chapter 6. We only cover the basics here so you can follow the order of initialization for simple programs.