2011-10-07 35 views
0

这个Java程序简单,充满意见的,所以你可以fast.however理解,为什么在构建员工[1],该计划先去声明:java的构造为了

this("Employee #" + nextId, s); 

然后去对象初始化块,然后回到说法,怎么confusion.why不是第一次使用对象初始化块

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++; 
    } 
} 
+2

什么问题? – MasterCassim

+0

听起来就像你在问为什么'this'语句在实例初始化块之前执行。那是对的吗? –

回答

4

因为this("Employee #" + nextId, s);包括对父类的构造的隐式调用,这当然必须执行之前的初始化块子类。

使用实例初始值设定器通常是一个坏主意,因为它们不是众所周知的,除了构造函数之外不能做任何事情,混合两者都会导致混淆。

+0

thx.this真的是一个坏主意。 – huateng

1

这是继节8.8.7.1 of the JLS指定的顺序:

(最终两颗子弹)

设C是类被实例化,令S是C的直接超类,让我是实例正在创建。一个明确的构造函数调用进行的评价如下:

  • 首先,如果构造函数调用语句是一个父类的构造函数调用, (剪断,因为它不是在我们的例子)
  • 接下来,构造函数被调用。最后,如果构造函数调用语句是超类构造函数调用,并且构造函数调用语句正常完成,那么将执行C的所有实例变量初始值设定项和C的所有实例初始值设定项。 (Snip)另一个构造函数调用不执行这个额外的隐式操作。

因此实例初始化执行超类后立即被称为 - 这是从public Employee(String n, double s)(隐含的)。这应该在执行该双参数构造函数的主体之前发生。

0

不确定实际问题是什么,这有点令人困惑。初始化的顺序(静态,对象,构造函数)是预定义的,并且与它们在代码中出现的顺序无关。至于一般风格,我通常不鼓励使用对象初始化块。这是一个非常常见的错误来源,它使异常处理更加复杂,并且很难调试。另外,它不是一个很常见的模式,因此开发人员在分析错误时往往会错过寻找它。

0

Java编译器必须确保从每个构造函数调用对象初始化块中的代码。对于大多数构造函数,它通过在隐式或显式调用super()之后将代码插入构造函数来完成此操作。对于以this()开头的编译器,首先不隐式调用super() - 另一个构造函数处理它。其次,在这样的构造函数中,根本不能插入对象初始化块,因为当调用第二个构造函数时,代码将被拾取。因此,this()呼叫是发生的第一件事。