java类和实例的初始化过程

当new一个对象,特别是含有继承关系的对象时,java初始化的步骤是什么?首先明确java分类初始化< clinit >()实例初始化< init >()
java的类定义中,静态变量及其赋值语句、静态代码块、静态方法属于类的范畴,他们的初始化在< clinit >()时进行。而变量,代码块、方法等属于实例的范畴,他们的初始化在< init >()时进行。
在new一个对象时,如果类还没有被初始化,首先进行类的初始化。在类的初始化过程中:

  • 虚拟机会保证在子类的< clinit >()执行之前,父类的< clinit >()先执行。因此,在虚拟机中第一个被执行的< clinit >()一定是java.lang.Object。
  • < clinit >()方法是由编译器自动收集类中的所有类变量的赋值动作和静态语句块中的语句合并产生的,编译器收集的顺序是根据其在源文件中的顺序决定的,静态语句块中仅能访问到定义在静态语句块之前的变量,定义在它之后的变量,在前面的静态语句中可以赋值,但不能访问。例如
public class Test{
  static{
      i = 0; //合法
      //System.out.println(i);//不能引用,不合法
  }
  public static int i = 1;
  public static void main(String [] args){
    System.out.println(i);
  }
}

此时输出的i值应该为1,因为等于1的赋值语句在后面。
又如:

static class Parent{
  public static int a = 1;
  static {
    a = 2;
 }
}
static class Sub extends Parent{
  public static int b = a;
}

public static void main(String [] args){
  System.out.println(Sub.b);
}

由于Parent将在Sub之前初始化,即a=2将在public static int b = a; 这句之前执行,因此,输出b的值应为2。

在类初始化完之后,进行实例的初始化< init >():
例如:

public class Parent{
  public static String pStaticStr = "parent static string";
  public String pStr = "parent instance string";
  static{
    System.out.println("parent static fields");
    System.out.println(pStaticStr);
 }
 {
   System.out.println("parent instance fields");
   System.out.println(pStr);
 }

  public Parent(){
    System.out.println("parent instance initialization");
 }
}

public class Sub extends Parent{
 public static String sStaticStr = "sub static string";
  public String sStr = "subinstance string";
  static{
    System.out.println("substatic fields");
    System.out.println(sStaticStr);
 }
 {
   System.out.println("sub instance fields");
   System.out.println(sStr);
 }

  public Sub(){
    System.out.println("sub instance initialization");
 }
 
  public static void main(String[] args){
    System.out.println("sub main");
    new Sub();
 }
}

在运行Sub中的main函数最终的结果如下:


输出结果

过程如下,在执行main函数时,将要先对Sub进行类初始化,此时应该先对Sub的父类Parent进行类初始化,因此执行Parent的静态代码块,输出

parent static fields
parent static string

随后,进行Sub的类初始化,执行Sub的静态代码块:

sub static fields
sub static string

然后main函数开始执行,输出

sub main

由于在执行main函数的时候,Parent和Sub已经完成了类的初始化,因此,在调用 new Sub()只需要完成实例的初始化:
实例的初始化同样遵循先初始化父类的顺序。
先初始化父类的变量字段和代码块,因此输出

parent instance fields
parent instance string

随后调用父类的构造函数,输出:

parent instance initialization

父类实例初始化完成,随后子类同样按照先变量字段和代码块后构造函数的顺序初始化。
同样的道理,如果将Sub类的main函数去掉,改为在另一个Test类中调用new Sub,如下:

public class Test{
public static void main(String[]args){
    System.out.println("main");
    newSub();
    System.out.println("\n");
    newSub();
  }
}

最后的输出结果将是:

输出结果

总结:整个new的过程,如果类已经被初始化,则直接初始化实例,按照父类实例变量和代码块->父类构造器->子类实例变量和代码块->子类构造器的顺序执行。如果类还没有被初始化,应先初始化类,再初始化实例。初始化类的时候同样应先初始化父类,顺序要按照代码中的顺序。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,684评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,143评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,214评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,788评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,796评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,665评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,027评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,679评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,346评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,664评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,766评论 1 331
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,412评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,015评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,974评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,073评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,501评论 2 343

推荐阅读更多精彩内容

  • 搜索的时候看了好几篇文,自己就想记录一遍,加深一下记忆,以下是原文的地址,受益匪浅。blog.csdn.net/n...
  • 本文根据《深入理解java虚拟机》第7章内容整理 一、基本概念 虚拟机把描述类的数据从Class文件加载到内存,并...
    梦工厂阅读 2,763评论 1 31
  • Java的初始化可以分为两个部分:(a)类的初始化(b)对象的创建(a)类的初始化 **一、概念介绍: ** 一个...
    梦工厂阅读 4,171评论 1 24
  •   最近在看回顾Java基础的时候,发现看似很简单的类初始化的顺序却并不是那么简单(往往越是简单的东西反而越容易出...
    BrightLoong阅读 1,484评论 0 2
  • 一个月前,对于轮岗,是千般不舍得,万般不愿意,这一大群孩子,丢下一个月,会成了什么样子,一个月的日子不就白白浪费了...
    月亮河畔阅读 1,254评论 3 4