标题起得略拗口,大概意思就是说在一个Java类中,域和构造方法的调用顺序。

1. 没有继承的情况

单独一个类的场景下,初始化顺序为依次为 静态数据,继承的基类的构造函数,成员变量,被调用的构造函数。

其中静态数据只会初始化一次。

package com.khlin.binding.test;

public class App2 {
public static void main(String[] args) {
Son son = new Son();
}
} class Son { public Son() {
System.out.println("this is son.");
} public Son(int age) {
System.out.println("son is " + age + " years old.");
} private Height height = new Height(1.8f); public static Gender gender = new Gender(true);
} class Height {
public Height(float height) {
System.out.println("initializing height " + height + " meters.");
}
} class Gender {
public Gender(boolean isMale) {
if (isMale) {
System.out.println("this is a male.");
} else {
System.out.println("this is a female.");
}
}
}

输出:

2. 继承的情况

稍微修改一下代码,添加两个基类,让Son继承Father, Father继承Grandpa。

继承的情况就比较复杂了。由于继承了基类,还将往上回溯,递归地调用基类的无参构造方法。

在我们的例子中,在初始化静态数据后,会先往上追溯,调用Father的默认构造方法,此时再往上追溯到Grandpa的默认构造方法。

注:如果在子类的构造方法中,显式地调用了父类的带参构造方法,那么JVM将调用指定的构造方法而非默认构造方法。

基类和子类均有静态数据,成员变量和构造方法的场景

我们继续修改代码,让其最终呈现如下:

 package com.khlin.binding.test;

 public class App2 {
public static void main(String[] args) {
Son son = new Son();
}
} class Grandpa {
public Grandpa() {
System.out.println("this is grandpa.");
} public Grandpa(int age) {
System.out.println("grandpa is " + age + " years old.");
} private Height height = new Height(1.5f); public static Gender gender = new Gender(true, "grandpa");
} class Father extends Grandpa { public Father() {
System.out.println("this is father.");
} public Father(int age) {
System.out.println("father is " + age + " years old.");
} private Height height = new Height(1.6f); public static Gender gender = new Gender(true, "father");
} class Son extends Father { public Son() {
super(50);
System.out.println("this is son.");
} public Son(int age) {
System.out.println("son is " + age + " years old.");
} private Height height = new Height(1.8f); public static Gender gender = new Gender(true, "son");
} class Height {
public Height(float height) {
System.out.println("initializing height " + height + " meters.");
}
} class Gender {
public Gender(boolean isMale) {
if (isMale) {
System.out.println("this is a male.");
} else {
System.out.println("this is a female.");
}
} public Gender(boolean isMale, String identify) {
if (isMale) {
System.out.println(identify + " is a male.");
} else {
System.out.println(identify + " is a female.");
}
}
}

最后输出会是什么呢?

参考下面另一个案例的分析。链接:http://bbs.csdn.net/topics/310164953

在我们的示例中,加载顺序应该是这样的:

Grandpa 静态数据

Father 静态数据

Son 静态数据

Grandpa 成员变量

Grandpa 构造方法

Father 成员变量

Father 构造方法

Son 成员变量

Son 构造方法

所以输出如下:

Java类加载及实例化的调用顺序的更多相关文章

  1. java 类加载及实例化的调用顺序

    1.没有继承的情况 单独一个类的场景下,初始化顺序为依次为 静态变量和静态代码块(看两者的书写顺序),继承的基类的构造函数,成员变量,被调用的构造函数. 代码呈现: public class Test ...

  2. Java类加载器加载类顺序

    java ClassLoader的学习 java是一门解释执行的语言,由开发人员编写好的java源文件先编译成字节码文件.class形式,然后由java虚拟机(JVM)解释执 行,.class字节码文 ...

  3. Java父类与子类方法调用顺序

    父类 FatherClass package 父类与子类方法调用顺序; /** * 父类 * @author shundong * */ public class FatherClass { priv ...

  4. java类加载机制及方法调用

    类加载机制 概述 类从被加载到虚拟机内存中开始,到卸载出内存为止,它的整个生命周期包括:加载(Loading).验证(Verification).准备(Preparation).解析(Resoluti ...

  5. Java 类的构造器的调用顺序

    规则如下: 对于一个复杂的对象,构建器的调用遵照下面的顺序: (1) 调用父类构建器.这个步骤会不断重复下去,首先得到构建的是分级结构的根部,然后是下一个子类,等等.直到抵达最深一层的子类. (2) ...

  6. java和C#实例化类初始化顺序

    c# 初始化顺序 子类的静态字段 子类的静态构造方法 子类的实例字段 父类的静态字段 父类的静态构造方法 父类的实例字段 父类的实例构造方法 java 初始化顺序 初始化过程: 1. 初始化父类中的静 ...

  7. java实例变量及方法调用顺序

    public class Base { private String name="base"; public Base(){ sayHello(); } void sayHello ...

  8. java 实例化是调用了子类重写方法

    java 实例化时调用了抽象方法或者class里面某个方法,如果子类有重写改方法,实际运行的是子类重写方法 package auto.test; //抽象父类 public abstract clas ...

  9. Java学习笔记11---静态成员变量、静态代码块、成员变量及构造方法的初始化或调用顺序

    当创建一个对象时,各种成员变量及构造方法的初始化或调用顺序是怎样的呢? (1).如果类尚未加载,则先初始化静态成员变量和静态代码块,再初始化成员变量,最后调用相应的构造方法: (2).如果类已经加载过 ...

随机推荐

  1. LoadLibraryEx及发回hmodule的一些细节

    LoadLibraryEx可以配合 DONT_RESOLVE_DLL_REFERENCES LOAD_LIBRARY_AS_DATAFILE LOAD_LIBRARY_AS_DATAFILE_EXCL ...

  2. c#集合类的线程安全

    即位于System.Collections命名空间下的集合,如Hashtable,ArrayList,Stack,Queue等.其均提供了线程同步的一个实现 集合线程同步的问题 public clas ...

  3. redis 用setbit(bitmap)统计活跃用户

    getspool.com的重要统计数据是实时计算的.Redis的bitmap让我们可以实时的进行类似的统计,并且极其节省空间.在模拟1亿2千8百万用户的模拟环境下,在一台MacBookPro上,典型的 ...

  4. UVa 11752 - The Super Powers 数学

    请看这个说明http://blog.csdn.net/u014800748/article/details/45914353 #define _CRT_SECURE_NO_WARNINGS #incl ...

  5. spilt用法简介

    //获取墓位位置 string MWFLMC = "和平区祥和园D组A碑11排"; //得到字符数组 ]; //分割字符数组 sArray1 = MWFLMC.Split(] { ...

  6. jps 显示process information unavailable解决方法

    jps 显示process information unavailable解决办法jps时出现如下信息: 4791 -- process information unavailable 解决办法: 进 ...

  7. bzoj 3033 太鼓达人

    思路:首先一定是2^m次方的总数.用二进制从 000 一直到 111总过m个数,然后暴搜. #include<cstdio> #include<cstring> #includ ...

  8. (原)Eclipse Tomcat配置(2014.12.27——By小赞)

    Eclipse中配置自己已经安装的Tomcat 首先为Eclipse安装Tomcat插件: 进入Tomcat插件下载页:http://www.eclipsetotale.com/tomcatPlugi ...

  9. POJ3750: 小孩报数问题+一道经典约瑟夫问题(猴子选大王)

    又一次因为一个小错误,POJ上Wrong Answer了无数次..... 在差不多要放弃的时候,发现了这个猥琐的不能再猥琐的bug,改完了提交就AC了,简直无语.... 本题wo采用模拟方法: 1 # ...

  10. glusterfs repo

    Installing Gluster For RPM based distributions, if you will be using InfiniBand, add the glusterfs R ...