随笔-204  评论-149  文章-0  trackbacks-0
 

JAVA中子类对象的实例化过程

 Person.java

class Person
{
 
public String name = "not know";//4
 public int age = -1 ;//5
 public Person()
 
{    
 }
 
public Person(String name , int age)//3
 {
  
this.name = name ;//6
  this.age = age;//7
 }
 
public void showInfo()
 
{
  System.out.println("Name is :"+name+" Age is :"+age);
 }
}
class Student extends Person
{
 
public String school = "not konwn";//8
    public Student()
    
{
     
super();    
    }
    
public Student (String name ,int age, String school)  //1
    {
     
super(name,age);  //2
     this.school = school;//9
    }
    
public void showInfo()
    
{
     
super.showInfo();
     System.out.println("School is :"+school);
    }
}

AllTest.java

class AllTest
{
 
public static void main(String[]args)
 
{
  Student stA = 
new Student("wanghao",20,"qinghuadaxue"); //0
 }
}

其语句的执行顺序是怎样的呢?
java
中,在使用new操作符创建一个类的实例对象的时候,开始分配空间并将成员变量初始化为默认的数值,注意这里并不是指将变量初始化为在变量定义处的初始值,而是给整形赋值0,给字符串赋值null 这一点于C++不同,(student.name = null , student.age = 0
然后在进入类的构造函数。

在构造函数里面,首先要检查是否有this或者super调用,this调用是完成本类本身的构造函数之间的调用,super调用是完成对父类的调用。二者只能出现一个,并且只能作为构造函数的第一句出现。在调用thissuper的时候实现程序的跳转,转而执行被调用的this构造函数或者super构造函数。
thissuper执行完毕,程序转而执行在类定义的时候进行的变量初始化工作
这个执行完毕,才是构造函数中剩下的代码的执行。
执行顺序已经用绿色标出。

Order of initialization
Within a class, the order of initialization is determined by the order that the variables are defined within the class. The variable definitions may be scattered throughout and in between method definitions, but the variables are initialized before any methods can be called—even the constructor. For example: Feedback
//: c04:OrderOfInitialization.java
// Demonstrates initialization order.
import com.bruceeckel.simpletest.*;

// When the constructor is called to create a
// Tag object, you'll see a message:
class Tag {
  Tag(int marker) {
    System.out.println("Tag(" + marker + ")");
  }
}

class Card {
  Tag t1 = new Tag(1); // Before constructor
  Card() {
    // Indicate we're in the constructor:
    System.out.println("Card()");
    t3 = new Tag(33); // Reinitialize t3
  }
  Tag t2 = new Tag(2); // After constructor
  void f() {
    System.out.println("f()");
  }
  Tag t3 = new Tag(3); // At end
}

public class OrderOfInitialization {
  static Test monitor = new Test();
  public static void main(String[] args) {
    Card t = new Card();
    t.f(); // Shows that construction is done
    monitor.expect(new String[] {
      "Tag(1)",
      "Tag(2)",
      "Tag(3)",
      "Card()",
      "Tag(33)",
      "f()"
    });
  }
} ///:~


//: c04:StaticInitialization.java
// Specifying initial values in a class definition.
class Bowl {
  Bowl(int marker) {
    System.out.println("Bowl(" + marker + ")");
  }
  void f(int marker) {
    System.out.println("f(" + marker + ")");
  }
}

class Table {
  static Bowl b1 = new Bowl(1);
  Table() {
    System.out.println("Table()");
    b2.f(1);
  }
  void f2(int marker) {
    System.out.println("f2(" + marker + ")");
  }
  static Bowl b2 = new Bowl(2);
}

class Cupboard {
  Bowl b3 = new Bowl(3);
  static Bowl b4 = new Bowl(4);
  Cupboard() {
    System.out.println("Cupboard()");
    b4.f(2);
  }
  void f3(int marker) {
    System.out.println("f3(" + marker + ")");
  }
  static Bowl b5 = new Bowl(5);
}

public class StaticInitialization {
  static Test monitor = new Test();
  public static void main(String[] args) {
    System.out.println("Creating new Cupboard() in main");
    new Cupboard();
    System.out.println("Creating new Cupboard() in main");
    new Cupboard();
    t2.f2(1);
    t3.f3(1);
    monitor.expect(new String[] {
      "Bowl(1)",
      "Bowl(2)",
      "Table()",
      "f(1)",
      "Bowl(4)",
      "Bowl(5)",
      "Bowl(3)",
      "Cupboard()",
      "f(2)",
      "Creating new Cupboard() in main",
      "Bowl(3)",
      "Cupboard()",
      "f(2)",
      "Creating new Cupboard() in main",
      "Bowl(3)",
      "Cupboard()",
      "f(2)",
      "f2(1)",
      "f3(1)"
    });
  }
  static Table t2 = new Table();
  static Cupboard t3 = new Cupboard();
} ///:~


继承情况下的初始化
了解一下包括继承在内的初始化的过程将是非常有益的,这样就能有个总
体的了解。看看下面这段代码:
//: c06:Beetle.java
// The full process of initialization.
class Insect {
  protected static Test monitor = new Test();
  private int i = 9;
  protected int j;
  Insect() {
    System.out.println("i = " + i + ", j = " + j);
    j = 39;
  }
  private static int x1 = print("static Insect.x1 initialized");
  static int print(String s) {
    System.out.println(s);
    return 47;
  }
}

public class Beetle extends Insect {
  private int k = print("Beetle.k initialized");
  public Beetle() {
    System.out.println("k = " + k);
    System.out.println("j = " + j);
  }
  private static int x2 = print("static Beetle.x2 initialized");
  public static void main(String[] args) {
    System.out.println("Beetle constructor");
    Beetle b = new Beetle();
    monitor.expect(new String[] {
      "static Insect.x1 initialized",
      "static Beetle.x2 initialized",
      "Beetle constructor",
      "i = 9, j = 0",
      "Beetle.k initialized",
      "k = 47",
      "j = 39"
    });
  }
} ///:~

当你用Java 运行Beetle 的时候,第一件事就是访问了Beetel.main( )(这是一个static ),于是装载器(loader)就会为

你寻找经编译的Beetle 类的代码(也就是Beetle.class 文件)。在装载的过程中,装载器注意到它有一个基类(也就是extends 所要表示的意思),于是它再装载基类。不管你创不创建基类对象,这个过程总会发生。(试试看,把创建对象的那句注释掉,看看会有什么结果。)如果基类还有基类,那么这第二个基类也会被装载,以此类推下一步,它会执行“根基类(root bas e class)(这里就是Insect)static 初始化,然后是下一个派生类的static 初始化,以此类推。这个顺序非常重要,因为派生类的“静态初始化(即前面讲的static 初始化)”有可能要依赖基类成员的正确初始化。

现在所有必要的类都已经装载结束,可以创建对象了。首先,对象里的所有的primitive 都会被设成它们的缺省值,而reference 也会被设成null——这个过程是一瞬间完成的,对象的内存会被统一地设置成“两进制的零(binary zero)”。如果有对成员变量赋初值,则对成员变量进行赋值,然后调用基类的构造函数。调用是自动发生的,但是你可以使用super 来指定调用哪个构造函数(也就Beetle( )构造函数所做的第一件事)。基类的构造过程以及构造顺序,同派生类的相同。基类构造函数运行完毕之后,会按照各个变量的字面顺序进行初始化。最后会执行构造函数的其余部分。

posted on 2009-05-11 21:16 Frank_Fang 阅读(2396) 评论(1)  编辑  收藏 所属分类: Java编程C++编程

评论:
# re: java对象的实例化过程,成员变量的初始化顺序 2013-10-30 21:34 | 3a教程网

java变量的初始化及赋值
http://3aj.cn/article/1612.html  回复  更多评论
  

只有注册用户登录后才能发表评论。


网站导航: