标题起得略拗口,大概意思就是说在一个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. arcgis android 加载google切片 天地图切片 并且能进行缓存

    废话不多说,直接下载,看layer包! https://github.com/Young-Ken/android-gis

  2. 引用类型传递 ListView展示数据

    教师评分项目总结 //创建一个SE员工类 1.1       //首先分析项目 * 01.我需要在LIstView控件中显示三个员工的信息 * 那么可以定义一个长度为3的数组来承载要显示的数据 * 0 ...

  3. node系列2

    文件操作 NodeJS能够操作文件.小至文件查找,大至代码编译,几乎没有一个前端工具不操作文件.换个角度讲,几乎也只需要一些数据处理逻辑,再加上一些文件操作,就能够编写出大多数前端工具,本章将介绍与之 ...

  4. 代码-Weka的决策树类J48

    package kit.weka;   /** * desc:试试Weka的决策树类 * <code>J48Test</code> * */ import java.io.Fi ...

  5. 教程-EhLib70的安装方法

    1.下载EhLib 5.2包2.将Common文件下的文件全部复制到DELPHI7目录下.3.打开DELPHI7.0程序:打开DclEhLib70.dpk文件包点“编译”->“安装”打开EhLi ...

  6. nyoj 282 You are my brother

    You are my brother 时间限制:1000 ms  |  内存限制:65535 KB 难度:3   描述 Little A gets to know a new friend, Litt ...

  7. [一]初识SpringMVC

    是什么? web开发框架 为什么用? 功能强大 怎么做? 1.导入jar包 2.配置web.xml <?xml version="1.0" encoding="UT ...

  8. php-fpm正在生成页面时,浏览器刷新后,php-fpm会退出吗?

    好久没写博客了,因为没有啥可写. 之所以有此疑问,是因为看了一篇大牛的文章:PHP升级导致系统负载过高问题分析.看完后,其中有些文字触发了我这个想法,也想验证一下. 方案,用tcpdump抓包,用st ...

  9. Sqlite在Windows、Linux 和 Mac OS X 上的安装过程

    一:在 Windows 上安装 SQLite 1,下载 请访问SQLite下载页面http://www.sqlite.org/download.html,从Windows 区下载预编译的二进制文件.需 ...

  10. UVA 557 - Burger(概率 递推)

     Burger  When Mr. and Mrs. Clinton's twin sons Ben and Bill had their tenth birthday, the party was ...