java中的初始化顺序

由于自己对java类中初始化顺序一直很困惑,所以最近仔细的翻看了一些资料,总结了一点学习心得,希望能和大家一起分享.

  ①构造器的初始化顺序

package cai.Init;

/**
*由输出可以看到
*House类中Window对象的定义不论是在House之前还是之后,都是首先执行Window对象的定义,
*然后才开始执行Constructor的初始化,当然变量的初始化也是这样
*/

class Window {
public Window(int i){
  System.out.println("The Window "+i+" is show!") ;
}
}

class House {
Window a = new Window(1);  // before constructor
public House(){
         System.out.println("The House is show!") ;
       a = new Window(2);    // in constructor
}
Window b = new Window(3);  // after constructor

}
public class InitConstr {
public static void main(String[] args) {
       new House();
}
}
/* out put->
The Window 1 is show!
The Window 3 is show!
The House is show!
The Window 2 is show!
*/

②static的初始化
package cai.Init;

/**
*   类InitStatic中,Window的static对象定义是在非static之前当然也在constructor之前,
*   并且static的初始化仅仅只是一次,而非static当重复调用时被初始化多次,不论是非static还是
*   static的初始化都需要激发该类的初始化,否则对象的初始化将永远不会得到执行,就向下面Table中的
*   window d将永远不会执行一样
*/
class Window {
public Window(String i){
           System.out.println("The Window "+i+" is show!") ;
}
}

class Table {
static Window d = new Window("d");     //never match
}

class House {
Window a = new Window("a");          //before static and constructor
static Window b = new Window("b");  
public House() {
  System.out.println("The House is show!") ;
}
static Window c = new Window("c");
}
public class InitStatic {
  static House house =  new House();
  public static void main(String args[]) {
   new House();
  }
}

/*output
* The Window b is show!
   The Window c is show!
   The Window a is show!
   The House is show!
   The Window a is show!
   The House is show!
*/

总结一下吧:
1.假设有个Dog类,即使构造器没有显示的说明为static的,它也是static的,所以在首次创建dog类对象或者加载dog类对象成员时,java解析器都要去定位Dog.class文件.
2.然后载入Dog.class对象,这将创建一个Class对象,所有的static成员将被加载,这也就是为什么static只被加载一次的原因.
3.当用new Dog()创建对象时将在堆中为该对象分配足够大的空间,并把该对象中的各种成员变量初始化,int 被初始化为0,boolean被初始化为false,而引用则被设置成为null,等等。
4.执行所有字段定义处的初始化动作,也就是在类中的各种成员定义.
5.最后执行构造函数,这或许会有继承关系所以将牵扯到一系列的调用动作。

③下面来看看一个较复杂点的例子,并和继承关联起来
package cai.Init;

/**
* 我们来仔细分析下面类的加载顺序,当编译器通过static main()函数加载InheritInit类时,首先会加载各种static成员
* 所以首先初始化f,在这过程中初始化了该类的display方法,但在同等条件下的show方法却为能被执行,
* 因为没有类或对象的任何调用,它虽然是static的但它也为能被初始化,同等条件下的String e也是这样,
* 因为没有生成任何对象所以它也未能得到初始化,好啦,下面来看看其它类的初始化工作,由于main方法中的new House()的
* 调用,使得House类被加载,在加载时发现House的父类为Window所以会先加载Window,这里的初始化工作和 InheritInit
* 中的相似,所以static成员被加载,执行①,然后会找到子类中的static成员执行②,
* 在所有的static被执行完后,初始化对象的成员变量,因为有继承的关系所以首先执行③,再初始化构造函数Window,
* 最后初始化④,再执行构造函数House
*/
class Window {

String d = display("d");  //③
public Window() {
  System.out.println("The Window constrctor is called!");
}

static String display(String str) {
  System.out.println("The "+str+" is called!") ;
  return str;              //没有实际作用,只是为了为static成员变量初始化时调用该方法提供方便
}
    static String a = display("a");        //①
}

class House extends Window{

static String display(String str) {
  System.out.println("The "+str+" is called!") ;
  return str;              //没有实际作用,只是为了为static成员变量初始化时调用该方法提供方便
}
    static String b = display("b");       //②
    String c = display("c");              //④
public House() {
  System.out.println("The House constructor is called!");
}

}
public class InheritInit {
   
String e = display("e");           //没有构造函数的激发它将永远不被调用
public static void main(String[] args) {
           new House();
}

static String display(String str) {
  System.out.println("The "+str+" is called!") ;
  return str;              //没有实际作用,只是为了为static成员变量初始化时调用该方法提供方便
}
static String f = display("f");

static void Show() {         //没有类或对象任何调用虽然是static的但它也为能被初始化
  System.out.println("is show!");
}
}
/*output
* The f is called!
   The a is called!
   The b is called!
   The d is called!
   The Window constructor is called!
   The c is called!
*/

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值