继承情况下的初始化

时间:2022-03-24 16:27:51
Java 的所有东西都是对象,编译之后每个类都保存在它自己的文件里。不到需要的时候,这个文件是不会装载的。总之你可以说“类的代码会在它们第一次使用的时候装载”。类的装载通常都发生在第一次创建那个类的对象的时候,但是访问static 数据或static 方法的时候也会装载。
第一次使用static 数据的时候也是进行初始化的时候。装载的时候, static 对象和static 代码段会按照它们字面的顺序(也就是在程序中出现的顺序)进行初始化。当然static 数据只会初始化一次。
 
继承情况下的初始化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();
继承情况下的初始化        }

继承情况下的初始化}
  // /:~
继承情况下的初始化

继承情况下的初始化结果是:
继承情况下的初始化
" 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 base class)”(这里就是Insect)的static 初始化,然后是下一个派生类的static 初始化,以此类推。这个顺序非常重要,因为派生类的“静态初始化(即前面讲
要依赖基类成员的正确初始化。
现在所有必要的类都已经装载结束,可以创建对象了。首先,对象里的所有的primitive 都会被设成它们的缺省值,而reference 也会被设成null——这个过程是一瞬间完成的,对象的内存会被统一地设置成“两进制的零(binary zero)”。然后调用基类的构造函数。调用是自动发生的,但是你可以使用super 来指定调用哪个构造函数(也就是Beetle( )构造函数所做的第一件事)。基类的构造过程以及构造顺序,同派生类的相同。基类构造函数运行完毕之后,会按照各个变量的字面顺序进行初始化。最后会执行构造函数的其余部分。