new一个对象的初始化过程
###############################
今天总结一下,new对象的初始化过程。
###############################
首先,当不含static成员时,先看一下案例图:
如图所示,我们先定义相关类,Building,House(继承Building),Villa(继承House),同时,House有成员变量LivingRoom,LivingRoom有成员变量Bed和Desk。
具体代码实现如下:
//建筑
class Building {
public Building() {
System.out.println("Building");
}
}
//房子
class House extends Building{
public LivingRoom livingRoom = new LivingRoom();//卧室
public House() {
System.out.println("House");
}
}
//别墅
class Villa extends House{
public Villa () {
System.out.println("Villa");
}
}
//卧室
class LivingRoom {
public Bed bedFirst = new Bed();//床
public Desk deskFirst = new Desk();//桌子 public LivingRoom () {
System.out.println("LivingRoom");
}
}
//床
class Bed {
public Bed () {
System.out.println("Bed");
}
}
//桌子
class Desk {
public Desk () {
System.out.println("Desk");
}
}
此时,我们new Villa():
public class InitializeDemo {
@Test
public void testInitialize() {
Villa villa = new Villa();
}
}
执行结果为:
Building
Bed
Desk
LivingRoom
House
Villa
在此案例中,我们在创建Villa对象时,会先试着创建Villa的父类House的对象,但House也有父类Building,Building还有父类object。因此,实际上,本类会先创建object对象并初始化,在object对象创建并初始化后,会创建building对象,building对象没有成员变量,所以直接执行构造器,打印出building。
接着,开始创建house对象,house对象有成员变量livingRoom,因此,会先初始化livingRoom,创建livingRoom时,也会先创建livingRoom的父类object对象并初始化没其次再创建livingRoom实例,livingroom同样有两个成员变量bed和desk,因而会按两个成员变量的定义顺序,先后创建bed和desk。初始化成员变量成功后,执行livingroom的构造器,打印livingroom。初始化livingroom成功后,开始执行house的构造器,打印house。
最后,在house初始化成功后,执行了Villa的构造器,打印出Villa。
初始化成功。
其次,当有static成员时
class Family {
Family (Class className) {
System.out.println("创建Family对象");
System.out.println(className.getName());
}
}
class Person {
Person() {
System.out.println("创建Person对象");
}
public static Family family = new Family(Person.class);
static {
System.out.println("执行Person静态代码块");
}
{
System.out.println("执行Person代码块");
}
}
public class Student extends Person {
public Student() {
System.out.println("创建student对象");
}
{
System.out.println("执行Student代码块");
}
static {
System.out.println("执行Student静态代码块");
}
public static Family staticFamily = new Family(Student.class);
@Test
public void test() {
System.out.println("=============");
}
public Family family = new Family(Student.class);
}
执行结果:
创建Family对象
com.tca.thinkInJava.chap7.Person
执行Person静态代码块
执行Student静态代码块
创建Family对象
com.tca.thinkInJava.chap7.Student
执行Person代码块
创建Person对象
执行Student代码块
创建Family对象
com.tca.thinkInJava.chap7.Student
创建student对象
1.首先在执行@test方法时,必须创建student的实例对象。
2.要创建student的实例对象,第一步先加载student父类person和student类的字节码,并对相关静态成员变量进行初始化,执行静态代码块。
3.首先加载父类person字节码,静态成员变量public static family ,family优于静态代码块前声明,所以先对静态成员变量family进行初始化。创建family对象,打印“创建family对象”,“xxxxxx”。
4.加载完person字节码后,再加载student字节码。静态代码块再静态成员public static family staticfamily之前声明,所以先执行静态代码块,打印“执行student静态代码块”,在进行成员变量初始化,执行“创建family对象”,“xxxxxxxxxx”。
5.创建student父类person的实例对象,创建实例对象时,先进行非静态成员变量初始化和代码块的执行,在执行构造器方法。所以先打印“执行person代码块”,再打印“创建person对象”。父类对象创建和初始化完毕。
6.创建子类对象student,先进行非静态成员变量初始化和代码块的执行,在执行构造方法。代码块的声明再非静态成员变量声明之前,所以先执行代码块,打印“执行student代码块”,再对family进行初始化,创建family对象,打印“创建family对象”,“xxxxxxxxxxx”。
7.执行test测试方法。
总结:
当不含static成员时,我们new一个对象A时,首先会先创建A类的父类B的实例对象,如果B类仍有C类,会先创建父类C的对象,以此类推,是一个递归创建的过程;当该类的父类对象已经全部创建并初始化时,会对该类进行创建和初始化。但在对该类进行初始化时,会先初始该类对象的成员变量,再执行该类的构造方法。成员变量的初始化和代码块的执行顺序,由它们声明顺序决定的,按顺序依次初始化或执行,但均在构造器方法之前执行。
当有static成员时,在该类第一次被JVM加载时,静态成员变量只会被初始化一次,静态代码块只会被执行一次。会先加载父类字节码,再加载子类字节码,如果有创建某类的实例对象,也是在该类的父类和该类的字节码加载完成之后,才会实例化该类父类的实例对象和该类的实例对象。静态成员变量的初始化和静态代码块的执行顺序,是由它们的声明顺序决定的,按顺序依次初始化或执行。
new一个对象的初始化过程的更多相关文章
- java中对象产生初始化过程
以前面试的时候,很多公司的笔试题中有关new一个对象有关一系列初始化的过程的选择题目.请看下面的题目. class Parent { static { System.out.println(" ...
- Java对象相关元素的初始化过程
1.类的成员变量.构造函数.成员方法的初始化过程 当一个类使用new关键字来创建新的对象的时候,比如Person per = new Person();JVM根据Person()寻找匹配的类,然后找到 ...
- java 子类的实例化和代码块初始化过程
1,子类的实例化 1,子父类中的构造函数的特点. 在子类构造对象时,发现,访问子类构造函数时,父类也运行了. 为什么呢? 原因是:在子类的构造函数中第一行有一个默认的隐式语句. super(); 子类 ...
- -1-2 java 面向对象基本概念 封装继承多态 变量 this super static 静态变量 匿名对象 值传递 初始化过程 代码块 final关键字 抽象类 接口 区别 多态 包 访问权限 内部类 匿名内部类 == 与 equal
java是纯粹的面向对象的语言 也就是万事万物皆是对象 程序是对象的集合,他们通过发送消息来相互通信 每个对象都有自己的由其他的对象所构建的存储,也就是对象可以包含对象 每个对象都有它的类型 也就是 ...
- 【软件构造】-<笔记>-浅谈java中类的初始化过程
编写java程序时,每创建一个新的对象,都会对对象的内容进行初始化. 每一个类的方法中的局部变量都有严格的初始化要求,因此假如写出下面的程序: void f(){ int i; i++; } 编译时就 ...
- Spark-源码-TaskScheduler初始化过程, ClientActor向Master发送注册任务信息过程
Spark版本 1.3 Spark源码 Spark.createTaskScheduler TaskScheduler初始化过程 1.// SparkContext中 /** * Create a t ...
- Java 静态static关键字,main函数,对象的初始化过程,对象调用成员,单例模式的设计,静态代码块(6)
Java 静态static关键字,静态代码块详情参考:static的使用原理讲解http://www.cnblogs.com/itcqx/p/5519464.html main函数: java Mai ...
- SpringIOC初始化过程--详解
SpringIOC初始化过程 相信大家都知道Spring这个东西,我们经常来用他一些特性,比如说他的AOP,IOC,那今天就带大家解析下SpringIOC的加载过程. 我们来看一个例子 Annotat ...
- vue 快速入门 系列 —— Vue 实例的初始化过程
其他章节请看: vue 快速入门 系列 Vue 实例的初始化过程 书接上文,每次调用 new Vue() 都会执行 Vue.prototype._init() 方法.倘若你看过 jQuery 的源码, ...
随机推荐
- 深蓝词库转换2.5发布——支持微软五笔,支持Linux和macOS和更多命令行功能
最近利用晚上的时间,对很久没有新版本发布的深蓝词库转换进行了版本升级.本次升级主要包含的功能包括: 一.支持Win10自带的微软五笔输入法用户自定义短语的导入导出. 1.在转换输入法词库列表中选择“W ...
- C# IE环境 - 重置IE( 注册表)
IE设置,都可以通过注册表,修改.以下是一些常用的IE设置注册表修改~ 检查证书吊销 /// <summary> /// 检查证书是否吊销 /// </summary> /// ...
- Asp.Net Core 内置IOC容器的理解
Asp.Net Core 内置IOC容器的理解 01.使用IOC容器的好处 对接口和实现类由原来的零散式管理,到现在的集中式管理. 对类和接口之间的关系,有多种注入模式(构造函数注入.属性注入等). ...
- Java每日一面(Part1:计算机网络)[19/10/21]
作者:故事我忘了¢个人微信公众号:程序猿的月光宝盒 1.UDP简介 1.1UDP报文结构: Source Port:源端口 Destination Port:目标端口 Length:数据包长度 C ...
- echarts 柱状图+折线+文字倾斜及省略
效果图: 代码: <!DOCTYPE html> <html lang="en"> <head> <meta charset=" ...
- SwiftUI学习(一)
总览 如果你想要入门 SwiftUI 的使用,那 Apple 这次给出的官方教程绝对给力.这个教程提供了非常详尽的步骤和说明,网页的交互也是一流,是觉得值得看和动手学习的参考. 不过,SwiftUI ...
- 使用Jitpack发布自己的Android Library
版权声明:本文为xing_star原创文章,转载请注明出处! 本文同步自http://javaexception.com/archives/169 使用Jitpack发布自己的Android Libr ...
- Python完全平方数
python解题源代码如下: import math """ 简述:一个整数,它加上100和加上268后都是一个完全平方数 提问:请问该数是多少? Python解题思路分 ...
- 034.认证方式 | 基本认证 、Token认证、 AK/SK认证
认证方式 关于认证: https://www.cnblogs.com/badboyh2o/p/11068779.html https://www.cnblogs.com/badboyh2o/p/110 ...
- Fiddler 过滤掉无用域名
- 在 Fiters 一栏勾选Show only Internet Hosts 及Show only the following Hosts- 然后在下面输入需要保留的域名