Java类加载及实例化的调用顺序
标题起得略拗口,大概意思就是说在一个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类加载及实例化的调用顺序的更多相关文章
- java 类加载及实例化的调用顺序
1.没有继承的情况 单独一个类的场景下,初始化顺序为依次为 静态变量和静态代码块(看两者的书写顺序),继承的基类的构造函数,成员变量,被调用的构造函数. 代码呈现: public class Test ...
- Java类加载器加载类顺序
java ClassLoader的学习 java是一门解释执行的语言,由开发人员编写好的java源文件先编译成字节码文件.class形式,然后由java虚拟机(JVM)解释执 行,.class字节码文 ...
- Java父类与子类方法调用顺序
父类 FatherClass package 父类与子类方法调用顺序; /** * 父类 * @author shundong * */ public class FatherClass { priv ...
- java类加载机制及方法调用
类加载机制 概述 类从被加载到虚拟机内存中开始,到卸载出内存为止,它的整个生命周期包括:加载(Loading).验证(Verification).准备(Preparation).解析(Resoluti ...
- Java 类的构造器的调用顺序
规则如下: 对于一个复杂的对象,构建器的调用遵照下面的顺序: (1) 调用父类构建器.这个步骤会不断重复下去,首先得到构建的是分级结构的根部,然后是下一个子类,等等.直到抵达最深一层的子类. (2) ...
- java和C#实例化类初始化顺序
c# 初始化顺序 子类的静态字段 子类的静态构造方法 子类的实例字段 父类的静态字段 父类的静态构造方法 父类的实例字段 父类的实例构造方法 java 初始化顺序 初始化过程: 1. 初始化父类中的静 ...
- java实例变量及方法调用顺序
public class Base { private String name="base"; public Base(){ sayHello(); } void sayHello ...
- java 实例化是调用了子类重写方法
java 实例化时调用了抽象方法或者class里面某个方法,如果子类有重写改方法,实际运行的是子类重写方法 package auto.test; //抽象父类 public abstract clas ...
- Java学习笔记11---静态成员变量、静态代码块、成员变量及构造方法的初始化或调用顺序
当创建一个对象时,各种成员变量及构造方法的初始化或调用顺序是怎样的呢? (1).如果类尚未加载,则先初始化静态成员变量和静态代码块,再初始化成员变量,最后调用相应的构造方法: (2).如果类已经加载过 ...
随机推荐
- 使用vs2010进行驱动开发的补充
看到前面的一篇文章 ,在这里http://www.cnblogs.com/wubiyu/archive/2010/05/17/1737420.html vs2010配置驱动开发基本上按照如上所说就差不 ...
- wps 2012-2013 通杀漏洞(CVE-2013-3934)
测试方法: 本站提供程序(方法)可能带有攻击性,仅供安全研究与教学之用,风险自负! #!/usr/bin/python # Exploit Title: Kingsoft Office Writer ...
- Android学习之路——简易版微信为例(一)
这是“Android学习之路”系列文章的开篇,可能会让大家有些失望——这篇文章中我们不介绍简易版微信的实现(不过不是标题党哦,我会在后续博文中一步步实现这个应用程序的).这里主要是和广大园友们聊聊一个 ...
- Android 实用代码七段(一)
前言 这里积累了一些不常见确又很实用的代码,每收集7条更新一次,希望能对大家有用. 声明 欢迎转载,但请保留文章原始出处:) 博客园:http://www.cnblogs.com 农民伯伯: htt ...
- [Stephen]转载 如何提高测试用例评审效率
年前启动的项目,之前一直各种需求文档的评审,之后搁置了一段时间进行其他项目的测试,如今开始各个模块的测试点评审,项目较大,模块较多,仅需求点将近250个.由8个人负责分工完成,几乎每天一个会议对各模块 ...
- 曲面Shader
这是一个能让平面呈现出曲面效果的Shaer. 代码: Shader "Custom/CurvedWorld"{ Properties { // Diffuse texture _M ...
- Asp.Net MVC4新特性指南(2):新特性介绍
上一章讲解了最基本的MVC4说明.今天就介绍下几种新特性的使用例子: 就当大家有MVC3的基础了.在这个基础上在看下面的介绍就容易多了.1.Web API MVC4包括一个更好的解决方案:A ...
- POJ-3070Fibonacci(矩阵快速幂求Fibonacci数列) uva 10689 Yet another Number Sequence【矩阵快速幂】
典型的两道矩阵快速幂求斐波那契数列 POJ 那是 默认a=0,b=1 UVA 一般情况是 斐波那契f(n)=(n-1)次幂情况下的(ans.m[0][0] * b + ans.m[0][1] * a) ...
- POJ1423 - Big Number(Stirling公式)
题目大意 求N!有多少位 题解 用公式直接秒杀... 代码: #include<iostream> #include<cmath> using namespace std; # ...
- 如何将可执行文件打包至APK并运行(转)
原文链接:http://www.lupaworld.com/home.php?mod=space&uid=345712&do=blog&id=248921 好久没有写bolg了 ...