黑马程序员-面向对象(构造函数、构造代码块、静态代码块)

本文讲解了Java中构造函数的概念及使用方法,包括构造函数的初始化、构造代码块的作用及执行顺序,以及静态代码块的特点。并通过实例演示了对象创建过程中类内部的执行顺序。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

---------------------- ASP.Net+Android+IOS开发.Net培训、期待与您交流! ---------------------- 

 

构造函数的初始化

如果在类当中,没有写构造函数,在主函数创建该类对象的时候,java编译器会自动加上一个空参数和空方法体的构造函数。

但是有一点要注意的是,构造函数有下面这种

Person(int age)
{
	this.age = age;
}
Person(String name)
{
	this.name = name;
}
Person(String name,int age)
{
	this.name = name;
	this.age = age;
}

 

注意:如果类中没有定义一个无参构造,但是类中是存在有参的构造函数并且在创建对象的时候用以下方式创建

Person p1 = new Person();

这样会导致编译不通过,因为类中并不存在一个无参构造,但是类中并不是没有构造函数的,所以编译器此时不会自动再加上一个无参的构造函数

 

构造代码块的要点

构造代码块

class Person

{

private String name;

private int age;

{

System.out.println("coderun");//这一部分属于构造代码块

}

Person()

{

//this("hah");

System.out.println("personrun");

}

Person(String name)

{

//this();

this.name =name;

}

}


 

 

构造代码块是先于构造函数执行的,每创建一个对象都要执行一遍

作用:构造代码块是给所有对象进行统一的初始化

而构造函数是给特定的调用的对象初始化

问题是:既然两者都是一创建对象就执行,那为什么要单独写一个构造代码块而不都写进构造函数,我是这样理解的

其实也可以理解成,当一个类当中有多个构造函数的时候,那么如果没有构造代码块,每个构造函数里面同会有同样功能的一段代码,那么java这个语言就是面向对象的,重复性的东西可以提取出来,单独作为一个代码块,提高代码的复用性和健壮性,也就有了把构造函数里的东西单独封装成构造代码块

 

静态代码块的特点:随着类的加载而执行,而且只执行一次,并且优先于主函数优先执行,用于给类进行初始化的

构造代码块给所有对象初始化的

构造函数是给特定对象初始化的

三者的优先级为:静态代码块 >构造代码块 >构造函数

 

对象的初始化的时候,类的内部执行顺序问题

1.        运行以下代码片段,输出结果是?()

class X {

         Yb = new Y();

         X(){

                           System.out.print("X");

         }

}

 

class Y {

         Y(){

                           System.out.print("Y");

         }

}

 

public class Z extends X {

         Yy = new Y();

         Z(){

                           System.out.print("Z");

         }

 

         publicstatic void main(String[] args) {

                            new Z();

         }

}

 

子类对象的实例化过程:

创建对象的执行流程:
1        new通过构造器来开辟内存空间,其中包含了父类子对象的空间;
2        new把这个刚刚创建的对象引用给出构造器,new的工作完成了;
3        构造器(非委派)会先去调用父类构造器;
4        父类构造器先执行显示初始化语句;
5        父类构造器再执行自己的方法体内容,父类构造器工作结束了;
6        回到子类构造器,开始执行显示初始化语句;
7        再执行构造器的方法体内容;
8        返回这个引用,结束。

 

当父类,和子类有Static时,先初始化Static,再初始化子类的Static,再初始化父类的其他成员变量->父类构造方法->子类其他成员变量->子类的构造方法。
父类上层还有父类时,总是先执行最顶层父类的Static-->派生类Static-->派生类Static-->.......-->子类Static-->顶层父类的其他成员变量-->父类构造方法--> 派生类的其他成员变量--> 派生类构造方法--> ...............-->子类其他成员变量-->子类构造方法(摘自傲鸽的帖子)


我的理解:其实继承父类,在实例化子类的时候,调用父类构造方法其实还隐含了一个信息,就是会初始化父类的变量。
这样说会更好:实例化子类,先实例化父类(而不单单说只调用父类构造方法)
所以我这个代码的正确执行顺序应该是
new Z();--->先实例化父类(执行Y b = new Y();输出:Y,然后输出X),然后回到X类中,执行Y y = new Y();输出Y,最后再执行Z类的自身的构造函数,输出Z

所以最后的结果YXYZ就是这么来的

 


---------------------- ASP.Net+Android+IOS开发.Net培训、期待与您交流! ----------------------

详细请查看:http://edu.youkuaiyun.com 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值