博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
java对象创建过程与初始化顺序
阅读量:6259 次
发布时间:2019-06-22

本文共 2326 字,大约阅读时间需要 7 分钟。

hot3.png

java对象创建过程与初始化顺序

单个类,不含继承

1 假设有个名为Dog的类,当首次创建型为Dog的对象时(构造器可以看成静态方法),或者Dog类的静态方法/静态域首次被访问时,Java解释器必须查找类路径,以定位Dog.class文件。  

然后载入Dog.class(这将创建一个Class对象),有关静态初始化的动作都会执行。因此,静态初始化只在Class对象首次加载的时候进行一次。

2 当你用new Dog()创建对象的时候,首先将在堆上为Dog对象分配足够的存储空间。  

3 这块存储空间会被清零,这就自动地将Dog中的所有基本类型数据设置成了默认值(对数字来说就是0,对布尔型和字符型也相同),而引用则被置成了null

4执行所有出现于字段定义处的初始化动作,变量定义的先后顺序决定了初始化的顺序

5执行构造器。

存在继承关系的初始化

from:

1.分配空间。要注意的是,分配空间不光是分配子类的空间,子类对象中包含的父类对象所需要的空间,一样在这一步统一分配。在分配的空间的时候,会把所有的属性设置为默认值。

2.递归的构造父类对象。

3.初始化本类属性。

4.调用本类的构造方法。

class A{      int valueA = 100;      public A(){  valueA = 150; }}class B extends A {     int valueB = 200;    public B(){  valueB= 250; }}public calss TestInherit{     public static void main(Stirng []){          B b = new B();    }}

创建过程如下:

我们在main方法中创建了一个b对象,创建的过程如下:

1.分配空间。在分配空间时,会把B、A这两个对象的空间一次性都分配完毕,然后将这两个对象的属性都设置为默认值,这样,valueA、valueB这两个属性都被设置为0。

2.递归构造B对象的父类对象。这里,要构造的就是A类对象。

3.初始化B的属性。即把valueB赋值为200。

4.调用B的构造方法。

其中第2步,创建A类对象,不需要再重新分配空间,需要一下几步:

2.1 递归的构造A类对象的父类对象。创建的步骤与创建A类对象同理。此例中以为A没有任何的父类,没有任何的输出。

2.2 初始化A类属性。把valueA 赋值为100.

2.3 调用A类的构造方法。

总结一下,创建B类对象的步骤一共有5步

1.分配空间

2.初始化A类属性。

3.调用A类的构造方法.

4.初始化B的属性。

5.调用B的构造方法。

另外一个例子

/**父类*/package test;public class Father {	static	{ System.out.println("父类静态初始化块");}	{ System.out.println("父类初始化块");      }	private static int b = 1;	public Father() {		System.out.println("调用了父类无参构造器");	}	public Father(int b) {		this.b = b;		System.out.println("调用父类的有参构造器");	}}/**子类*/package test;public class Son extends Father {	static	{ System.out.println("子类静态初始化块"); }	{ System.out.println("子类初始化块");       }	private static int a =1;	public Son() {		System.out.println("调用子类的构造器");	}	public Son(int a){		this.a=a;		System.out.println("调用子类的有参构造器");	}}package test;public class Test {	public static void main(String[] args) {		Son son = new Son();	}}

打印语句:

    父类静态初始化块

   子类静态初始化块

   父类初始化块

   调用了父类无参构造器

   子类初始化块

   调用子类的构造器

如果构造器中调用了其他函数

package extend;public class A {	public A(){		draw();	}	public void  draw(){		System.out.println("调用了父类的draw方法");	}}package extend;public class B extends A{	public int i = 1;	public B(int i){		this.i=i;	}	public void draw(){		System.out.println("调用的子类的方法");		System.out.println("i 等于:"+i);	}	public static void main(String[] args) {		B b =  new B(5);	}}

输出

i 等于:0  

调用的子类的方法

原因:在调用父类的构造函数时,里面的draw调用的是子类的!而此时子类中i被初始化为0

转载于:https://my.oschina.net/hnuweiwei/blog/294186

你可能感兴趣的文章
国内外MD5在线解密网站
查看>>
【OC语法要闻速览】一、方法调用
查看>>
Git-命令行-删除本地和远程分支
查看>>
本文将介绍“数据计算”环节中常用的三种分布式计算组件——Hadoop、Storm以及Spark。...
查看>>
顺序图【6】--☆☆
查看>>
Docker Swarm 让你事半功倍
查看>>
[转]IC行业的牛人
查看>>
javaScript事件(四)event的公共成员(属性和方法)
查看>>
linux系统常用命令
查看>>
在 Word 中的受支持的区域设置标识符的列表
查看>>
Caffe + Ubuntu 14.04 64bit + CUDA 6.5 配置说明2
查看>>
An easy to use android color picker library
查看>>
Oracle SID爆破工具SidGuess
查看>>
批处理常用命令总结2
查看>>
解读ASP.NET 5 & MVC6系列(9):日志框架
查看>>
Android -- 自定义View小Demo,绘制钟表时间(一)
查看>>
信息检索Reading List
查看>>
JavaWeb_JavaEE_命名规则
查看>>
申小雨命案审理延期至3月5日 警方将翻译嫌犯口供
查看>>
自动精简配置&重复数据删除核心技术点及其经济效应探究
查看>>