Reputation: 13
This java program is easy and full of comment,so you can understand it fast.however,why in construct staff[1],the program first go to the statement:
this("Employee #" + nextId, s);
then go to the object initialization block,and then go back to the statement,how confusion.why not it first use the object initialization block
import java.util.*;
public class ConstructorTest
{
public static void main(String[] args)
{
// fill the staff array with three Employee objects
Employee[] staff = new Employee[3];
staff[0] = new Employee("Harry", 40000);
staff[1] = new Employee(60000);
staff[2] = new Employee();
// print out information about all Employee objects
for (Employee e : staff)
System.out.println("name=" + e.getName()
+ ",id=" + e.getId()
+ ",salary=" + e.getSalary());
}
}
class Employee
{
// three overloaded constructors
public Employee(String n, double s)
{
name = n;
salary = s;
}
public Employee(double s)
{
// calls the Employee(String, double) constructor
this("Employee #" + nextId, s);
}
// the default constructor
public Employee()
{
// name initialized to ""--see below
// salary not explicitly set--initialized to 0
// id initialized in initialization block
}
public String getName()
{
return name;
}
public double getSalary()
{
return salary;
}
public int getId()
{
return id;
}
private static int nextId;
private int id;
private String name = ""; // instance field initialization
private double salary;
// static initialization block
static
{
Random generator = new Random();
// set nextId to a random number between 0 and 9999
nextId = generator.nextInt(10000);
}
// object initialization block
{
id = nextId;
nextId++;
}
}
Upvotes: 0
Views: 4088
Reputation: 81694
The Java compiler must ensure that the code in the object initialization block is called from each constructor. For most constructors, it does this by inserting the code into the constructor right after the implicit or explicit call to super()
. For compilers that start with this()
, however, first of all there is no implicit call to super()
-- the other constructor handles that. Secondly, in such a constructor the object initializer block can't be inserted at all, since the code will be picked up when the second constructor is called. Therefore the this()
call is the very first thing that happens.
Upvotes: 0
Reputation: 27614
Not sure what the actual question is, it's a bit confusing. The order of initialization (static, object, constructor) is predefined and has nothing to do with in which order they appear in the code. As for the general style, I generally discourage using object initialization blocks. It's a very common source of errors, it makes exception-handling more complex and it's hard to debug. In addition, it's not a very common pattern so developers tend to miss looking for it when analyzing bugs.
Upvotes: 0
Reputation: 1500795
This follows the order specified in section 8.8.7.1 of the JLS:
(Final two bullets)
Let C be the class being instantiated, let S be the direct superclass of C, and let i be the instance being created. The evaluation of an explicit constructor invocation proceeds as follows:
- First, if the constructor invocation statement is a superclass constructor invocation, (Snipped because it's not in our case)
- Next, the constructor is invoked.
- Finally, if the constructor invocation statement is a superclass constructor invocation and the constructor invocation statement completes normally, then all instance variable initializers of C and all instance initializers of C are executed. (Snip) An alternate constructor invocation does not perform this additional implicit action.
So the instance initializer is executed immediately after the superconstructor is called - which is (implicitly) from public Employee(String n, double s)
. This should happen before the body of that two-parameter constructor is executed.
Upvotes: 1
Reputation: 346317
Because this("Employee #" + nextId, s);
includes an implicit call to the superclass constructor, which of course must be executed before the initializer block of the subclass.
Using instance initializers is generally a bad idea as they are not well known, cannot do anything more than constructors, and mixing both leads to confusion.
Upvotes: 4