Java对象创建阶段的代码调用顺序

在创建阶段系统通过下面的几个步骤来完成对象的创建过程

  • 为对象分配存储空间
  • 开始构造对象
  • 从超类到子类对static成员进行初始化
  • 超类成员变量按顺序初始化,递归调用超类的构造方法
  • 子类成员变量按顺序初始化,子类构造方法调用

本文重点演示第三步到第五步:

Grandpa类

 1 package com.xinye.test;
 2
 3 public class Grandpa {
 4     {
 5         System.out.println("执行Grandpa的普通块");
 6     }
 7     static {
 8         System.out.println("执行Grandpa的静态快");
 9     }
10     public Grandpa(){
11         System.out.println("执行Parent的构造方法");
12     }
13     static{
14         System.out.println("执行Grandpa的静态快222222");
15     }
16     {
17         System.out.println("执行Grandpa的普通快222222");
18     }
19 }

Parent类

 1 package com.xinye.test;
 2
 3 public class Parent extends Grandpa{
 4     protected int a = 111;
 5     {
 6         System.out.println("执行Parent的普通块");
 7     }
 8     static {
 9         System.out.println("执行Parent的静态快");
10     }
11     public Parent(){
12         System.out.println("执行Parent的构造方法");
13     }
14     public Parent(int a){
15         this.a = a ;
16         System.out.println("执行Parent的构造方法:InitParent(int a)");
17     }
18     static{
19         System.out.println("执行Parent的静态快222222");
20     }
21     {
22         System.out.println("执行Parent的普通快222222");
23     }
24 }

Child类

 1 package com.xinye.test;
 2
 3 public class Child extends Parent {
 4     {
 5         System.out.println("执行Child的普通块");
 6     }
 7     static {
 8         System.out.println("执行Child的静态快");
 9     }
10     public Child(){
11         super(222);
12         System.out.println("a = " + a);
13         System.out.println("执行Child的构造方法");
14     }
15     static{
16         System.out.println("执行Child的静态快222222");
17     }
18     {
19         System.out.println("执行Child的普通快222222");
20     }
21 }

测试类

 1 package com.xinye.test;
 2
 3 public class Test {
 4
 5     public static void main(String[] args) {
 6         /**
 7          *
 8          *  第一步:
 9          *      Grandpa如果有静态块,按照Grandpa的静态块声明顺序依次执行
10          *      Parent中如果有静态块,按照Parent中的静态块声明顺序依次执行
11          *      Child中如果有静态块,按照Child中的静态块声明顺序依次执行
12          *  第二部:
13          *      如果Grandpa中有普通块,按照Grandpa的普通块声明顺序依次执行
14          *          执行完毕后,执行被调用的构造方法(如果Parent调用了Grandpa中的特定构造;如果没有则调用默认构造)
15          *      如果Parent中有普通块,按照Parent的普通块的声明顺序依次执行
16          *          执行完毕后,执行被调用的构造方法(如果Child调用了Parent的特定构造;如果没有则调用默认构造)
17          *         如果Child中有普通块,按照Child的普通块的声明顺序依次执行
18          *             执行完毕后,执行被客户端调用的特定构造方法
19          */
20
21         new Child();
22     }
23 }

执行结果

 1 执行Grandpa的静态快
 2 执行Grandpa的静态快222222
 3 执行Parent的静态快
 4 执行Parent的静态快222222
 5 执行Child的静态快
 6 执行Child的静态快222222
 7 执行Grandpa的普通块
 8 执行Grandpa的普通快222222
 9 执行Parent的构造方法
10 执行Parent的普通块
11 执行Parent的普通快222222
12 执行Parent的构造方法:InitParent(int a)
13 执行Child的普通块
14 执行Child的普通快222222
15 a = 222
16 执行Child的构造方法

Java对象创建阶段的代码调用顺序

时间: 2025-01-04 11:41:01

Java对象创建阶段的代码调用顺序的相关文章

深入理解java虚拟机(二)HotSpot Java对象创建,内存布局以及访问方式

内存中对象的创建.对象的结构以及访问方式. 一.对象的创建 在语言层面上,对象的创建只不过是一个new关键字而已,那么在虚拟机中又是一个怎样的过程呢? (一)判断类是否加载.虚拟机遇到一条new指令的时候,首先会检查这个指令的参数是否能在常量池中定位到一个类的符号引用,并且检查这个符号代表的类是否被加载.解析并初始化.如果没有完成这个过程,则必须执行相应类的加载. (二)在堆上为对象分配空间.对象需要的空间大小在类加载完成后便能确定.之后便是在堆上为该对象分配固定大小的空间.分配的方式也有两种:

深度理解java虚拟机读书笔记(二)HotSpot Java对象创建,内存布局以及访问方式

内存中对象的创建.对象的结构以及访问方式. 一.对象的创建 在语言层面上,对象的创建只不过是一个new关键字而已,那么在虚拟机中又是一个怎样的过程呢? (一)判断类是否加载.虚拟机遇到一条new指令的时候,首先会检查这个指令的参数是否能在常量池中定位到一个类的符号引用,并且检查这个符号代表的类是否被加载.解析并初始化.如果没有完成这个过程,则必须执行相应类的加载. (二)在堆上为对象分配空间.对象需要的空间大小在类加载完成后便能确定.之后便是在堆上为该对象分配固定大小的空间.分配的方式也有两种:

C#与数据库访问技术总结(六)之Command对象创建SQl语句代码示例

Command对象创建SQl语句代码示例 说明:前面介绍了 Command 对象的方法和一些属性,回顾一下 Command对象主要用来执行SQL语句.利用Command对象,可以查询数据和修改数据. 在下面这段代码里,首先根据连接字符串创建一个SqlConnecdon连接对象,并用此对象连接数据源:然后创建一个SqlCommand对象,并用此对象的ExecuteNonQuery方法执行不带返回结果集的SQL语句. 1 //连接字符串 2 3 private static string strCo

Java对象创建过程补遗

一.static修饰的东东是属于这个类的,是所有的该类的实例共享的,因此它们的初始化先于实例对象的初始化. 二.Java中没有静态构造方法,但是有静态代码块.当类中同时存在静态代码块和静态成员变量声明语句时,它们谁先执行? 答:按照类中定义的从上到下顺序,谁在前面谁先执行. 三.当类中同时存在非静态代码块和非静态成员变量声明语句时,它们谁先执行? 答:按照类中定义的从上到下顺序,谁在前面谁先执行. 四.含有赋值的非静态成员变量声明语句,如 int v=4,其实这个语句的执行要分成两步进行.首先创

JAVA对象创建的过程(简单粗暴明了)

假设有个名为Cat类: 1.即使没有显示地使用static关键字,构造器实际上也是静态方法.因此在创建类型为Cat的对象时,或者Cat类的静态方法/静态域被首次访问时(被引用),java解释器必须查找类途径(classpath上查找),以定位Cat.class文件. 2,.然后类加载器载入Cat.class,有关静态初始化的所有动作都会执行.并且,静态初始化只在Class对象首次加载时进行一次(关键字为static,与类绑定,通过类便可以访问这一变量,同时该类的对象共享这一资源.) 3.当用ne

【java in think】构造器的调用顺序

class Meal { public Meal() { System.out.println("Meal()--构造啦!"); } } class Bread { public Bread() { System.out.println("Bread()--构造啦!"); } } class Cheese { public Cheese() { System.out.println("Cheese()--构造啦!"); } } class Let

java对象创建与内存模型总结

 1.JVM管辖的内存大致分为三个逻辑部分:java栈(Heap).java堆(JavaStack)和方法区(MethodArea).在JVM启动时创建,关闭时全部回收.  栈.本地方法栈.程序计数器:以线程为粒度,每个线程拥有自己的部分.而堆和方法区被所有线程共享.  堆:运行时的数据区域,程序(线程)运行时动态分配.  方法区:静态存储区,存储被装载到JVM中的class信息. 2.栈 i).存放基本类型的变量数据和对象的引用变量(变量本身存放在堆和常量池中). ii).java系统必须知道

Java对象创建的过程及对象的内存布局与访问定位

这里以HotSpot为例,且所说的对象指普通的Java对象,不包括数组和Class对象等. 1.对象创建的过程 类加载.解析.初始化:虚拟机遇到new时先检查此指令的参数是否能在常量池中找到类的符号引用,并检查符号引用代表的类是否被加载.解析.初始化,若没有则先进行类加载. 对象内存分配:类加载检查通过后,虚拟机为新生对象分配内存,对象所需内存大小在类加载完成后便可完全确定.分配内存的任务等同于从堆中分出一块确定大小的内存. 根据内存是否规整(即用的放一边,空闲的放另一边,是否如此与所使用的垃圾

HotSpot Java对象创建,内存布局以及访问方式

内存中对象的创建.对象的结构以及访问方式. 一.对象的创建 在语言层面上,对象的创建只不过是一个new关键字而已,那么在虚拟机中又是一个怎样的过程呢? (一)判断类是否加载.虚拟机遇到一条new指令的时候,首先会检查这个指令的参数是否能在常量池中定位到一个类的符号引用,并且检查这个符号代表的类是否被加载.解析并初始化.如果没有完成这个过程,则必须执行相应类的加载. (二)在堆上为对象分配空间.对象需要的空间大小在类加载完成后便能确定.之后便是在堆上为该对象分配固定大小的空间.分配的方式也有两种: