标题起得略拗口,大概意思就是说在一个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. jquery图片轮播插件slideBox

    效果预览: 源代码下载: jQuery图片轮播(焦点图)插件jquery.slideBox 特点:兼容IE6+,Chrome,Firefox,Opera,safari,可左右,可上下,可快可慢,可指定 ...

  2. SharePoint 2010 WSP包部署过程中究竟发生什么?

    转:http://www.xue163.com/158/6/1585365.html 在SharePoint 2010中,我们可以使用Visual Studio 2010轻松创建WSP包来安装Web ...

  3. oracle 实例名和服务名以及数据库名区别

    一.数据库名什么是数据库名?数据库名就是一个数据库的标识,就像人的身份证号一样.他用参数DB_NAME表示,如果一台机器上装了多全数据库,那么每一个数据库都有一个数据库名.在数据库安装或创建完成之后, ...

  4. bzoj 2434 [Noi2011]阿狸的打字机(fail树+离线处理+BIT)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=2434 [题意] 按照一定规则生成n个字符串,回答若干个询问:(x,y),问第x个字符串 ...

  5. 洛谷P1294 高手去散步

    洛谷1294 高手去散步 题目背景 高手最近谈恋爱了.不过是单相思.“即使是单相思,也是完整的爱情”,高手从未放弃对它的追求.今天,这个阳光明媚的早晨,太阳从西边缓缓升起.于是它找到高手,希望在晨读开 ...

  6. 洛谷P1220 关路灯

    洛谷1220 关路灯 题目描述 某一村庄在一条路线上安装了n盏路灯,每盏灯的功率有大有小(即同一段时间内消耗的电量有多有少).老张就住在这条路中间某一路灯旁,他有一项工作就是每天早上天亮时一盏一盏地关 ...

  7. HW4.12

    public class Solution { public static void main(String[] args) { int n = 0; while(n * n < 12000) ...

  8. vim 设置 swap file, 防止 同一个文件同时被多次打开,而且有恢复的功效

    在.vimrc里加入:   set swapfile   即可以使能swap file, swapfile的名字一般是      .filename.swp    (如     .doc.txt.sw ...

  9. devexpress中gridview控件编辑时改变输入法状态

    在win7环境下使用Devexpress中的SpinEdit控件,切换成中文[简/繁]输入法输入数字键时有不少输入法会重复产生数字如输入1会变成11,输入123会变成112233.使用SpinEdit ...

  10. 教程-Delphi操作快捷键

    ************************************************************** Delphi快捷键-全-高手用-南山古桃(新手)-同学共进 ******* ...