标题起得略拗口,大概意思就是说在一个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. JAX-WS(JWS)发布WebService

    WebService历来都很受重视,特别是Java阵营,WebService框架和技术层出不穷.知名的XFile(新的如CXF).Axis1.Axis2等. 而Sun公司也不甘落后,从早期的JAX-R ...

  2. 分享form表单提交问题

    前段时间做了一个form表单传值问题  当时觉得form表单的submit不就是提交form表单name的value值吗 ? 其实是对的  但是我做的是一个打印页面  需要把当前页面的元素传入下一个u ...

  3. Html笔记(八)其他标签

    <pre></pre> :此标签内封装的文本数据格式将保持原样,包括空格和缩进等格式.常用于页面中显示带有缩进层次的代码. <p></p> :段落标签, ...

  4. leetcode—triangle

    1.题目描述 Given a triangle, find the minimum path sum from top to bottom. Each step you may move to adj ...

  5. Linux串口调试

    shell方式 1.使用minicon -s配置串口并保存: 2.使用setserial /dev/ttyUSB0 -a等查看串口配置: 3.接收侧cat /dev/ttyUSB0等待串口输出: 4. ...

  6. 集群搭建:主机宽带拨号上网,虚拟机使用桥接模式,该如何ping通外网

    首先介绍一下看这篇文章需要的基础.需要了解虚拟机的 虚拟机的三种网络模式,有Linux基础知识,这些都是前提.首先介绍一下我的环境:主机:win7虚拟机:VMware Workstation 10虚拟 ...

  7. Add And Reset a Federation Server to a Federation Server Farm adfs ad

    Applies To: Active Directory Federation Services (AD FS) 2.0 After you install the Active Directory ...

  8. APNs消息推送完整讲解

    在项目的AppDelegate中的didFinishLaunchingWithOptions方法中加入下面的代码: [[UIApplication sharedApplication] registe ...

  9. Google正确搜索方法

    以下是目前所有的Google搜索命令语法,它不同于Google的帮助文档,因为这里介绍了几个Google不推荐使用的命令语法.大多数的Google搜索命令语法有它特有的使用格式,希望大家能正确使用.我 ...

  10. Asp.net 管道事件

    在处理该请求时将由 HttpApplication 类执行以下事件. 希望扩展 HttpApplication 类的开发人员尤其需要注意这些事件. 1. 对请求进行验证,将检查浏览器发送的信息,并确定 ...