`

java构造方法与成员初始化分析

 
阅读更多

package ibm;

public class TestConstructor{

public static void main(String[] args) {

Drived drived=new Drived();

System.out.println(drived.memeber);

}

}

 

class Base {

public Base(){

System.out.println("base constructor");

preprocess();

}

public void preprocess(){

System.out.println("base invoked");

}

}

 

class Drived extends Base{

public String memeber="set the string";

public Drived(){

System.out.println("drived constructor");

System.out.println(memeber);

memeber="set in constructor";

}

@Override

public void preprocess(){

System.out.println("drived invoked ");

memeber="set in proprocess ";

}

}

 

 

请问以上程序的打印输出什么?

base constructor

drived invoked 

drived constructor

set the string

set in constructor

 

 

程序的执行顺序是这样的;

1 进入Drived 构造函数。

2 Drived 成员变量的内存被分配。

3 Base 构造函数被隐含调用。

4 Base 构造函数调用preprocess(),这里调用的是Drived的preprocess()(多态性)。

5 Drived 的preprocess设置memeber值为 “set in proprocess”。

6 Drived 的成员变量初始化被调用。

7 执行Drived 构造函数体。

 

Java中的声明和初始化不能看成一体的。在C++的世界中,C++并不支持成员变量在声明的时候进行初始化,其需要你在构造函数中显式的初始化其成员变量的值,看起来很土,但其实C++用心良苦。在面

 

向对象的世界中,因为程序以对象的形式出现,导致了我们对程序执行的顺序雾里看花。所以,在面向对象的世界中,程序执行的顺序相当的重要 。

 

下面是对上面各个步骤的逐条解释。

进入构造函数。

为成员变量分配内存。

除非你显式地调用super(),否则Java 会在子类的构造函数最前面偷偷地插入super() 。

调用父类构造函数。

调用preProcess,因为被子类override,所以调用的是子类的。

于是,初始化发生在了preProcess()之后。这是因为,Java需要保证父类的初始化早于子类的成员初始化,否则,在子类中使用父类的成员变量就会出现问题。

正式执行子类的构造函数(当然这是一个空函数,居然我们没有声明)。

你可以查看《Java语言的规格说明书》中的 相关章节 来了解更多的Java创建对象时的细节。

 

C++的程序员应该都知道,在C++的世界中在“构造函数中调用虚函数”是不行的,Effective C++ 条款9:Never call virtual functions during construction or destruction,Scott Meyers已经解

 

释得很详细了。在语言设计的时候,“在构造函数中调用虚函数”是个两难的问题。

1 如果调用的是父类的函数的话,这个有点违反虚函数的定义。

2 如果调用的是子类的函数的话,这可能产生问题的:因为在构造子类对象的时候,首先调用父类的构造函数,而这时候如果去调用子类的函数,由于子类还没有构造完成,子类的成员尚未初始化,这

 

么做显然是不安全的。

C++选择了第一种,而Java选择了第二种。

C++类的设计相对比较简陋,通过虚函数表来实现,缺少类的元信息。

而Java类的则显得比较完整,有super指针来导航到父类。

 

 

原文来自 http://blog.csdn.net/haoel/article/details/4319793 

分享到:
评论

相关推荐

    实验四 类的构造方法与Java流程控制语句

    重载构造方法的目的是提供多种初始化对象的能力,使程序员可以根据实际需要选用合适的构造方法来初始化对象。程序源代码如下。 2、使用选择语句 程序功能:使用if...else 语句构造多分支,判断某一年是否为闰年。...

    java面试题静态加载顺序构造方法

    Java中的继承与静态static等的执行先后顺序的面试题 java面试题静态加载顺序构造方法 继承与static 面试题目如下:请写出程序执行完成之后的结果。...3、类初始化时,先初始化类的属性成员,在执行构造方法。

    Java面向对象程序设计方案练习题(1).doc

    为MyTime类定义构造方法 以方便创建对象时初始化成员变量。 再定义diaplay方法 用于将时间信息打印出来。 为MyTime类添加以下方法 addSecond(int sec) addMinute(int min) addHour(int hou) subSecond(int sec) ...

    Java程序设计C实验课题(5th)

    声明两个带有无参构造方法的类A和B,声明A的子类C,并且声明B为C的一个成员,不声明C的构造方法,编写测试代码,生成类C的实例对象,观察结果; 声明一个父类A,它只有一个非默认构造方法,声明A的子类B,B具有默认...

    JAVA程序设计实验

    (1) 定义一个Animal类,其中包括昵称、性别、体重属性,构造函数初始化各属性,显示各属性的成员函数、修改属性的成员函数。实现并测试这个类。 (2) 从上题的类中派生出Dog类,添加年龄属性。重载相应的成员方法...

    Java开发者文档,分享日常学习的一些小知识点 .rar

     ※在所有类成员初始化完成之后,才调用本类的构造方法创建对象。  构造方法的作用就是初始化。  (2) 静态对象的初始化  程序中主类的静态变量会在main方法执行前初始化。  不仅第一次创建对象时,类中的...

    【Java语言基础】初始化块

    文章目录【Java语言基础】初始化块使用初始化块静态初始化块总结代码 【Java语言基础】初始化块 初始化块又称为代码块。属于类中的第四大成员。本质上是一个方法,它也有方法体,但没有方法名,没有参数,没有返回,...

    JAVA基础知识精华总结 收藏

    ※在所有类成员初始化完成之后,才调用本类的构造方法创建对象。 构造方法的作用就是初始化。 (2) 静态对象的初始化 程序中主类的静态变量会在main方法执行前初始化。 不仅第一次创建对象时,类中的所有静态变量...

    Java类初始化顺序

    所有构造方法执行顺序如下: 执行父类的构造方法。没有继承默认继承的Object。Object会开辟一块内存,初始化所有数据为0、null、false等默认值 执行本类中的成员代码块。所有代码块是从上往下顺序执行的,所以代码...

    JAVA_《JAVA面向对象程序设计》实验报告_drawing_

    (2)构造方法包括一个公共的空构造方法,一个能够初始化所有成员变量的构造方法;(3)包括所有的setter和getter方法,其中setter方法要求对形参进行验证,例如长、宽和高都大于0;(4)功能方法包括计算表面积...

    建立一个名为Student的类,该类有以下几个私有成员变量:学生姓名、学号、性别、年龄。还有以下两个成员函数:一个用于初始化学生姓名、学号、性别和年龄的构造函数,一个用于输出学生信息的函数。编写一个主函数。声明一个学学生对象。然后调用成员函数在屏幕输出学生信息。

    还有以下两个成员函数:一个用于初始化学生姓名、学号、性别和年龄的构造函数,一个用于输出学生信息的函数。编写一个主函数。声明一个学学生对象。然后调用成员函数在屏幕输出学生信息。 编程环境:vs2010,语言:...

    无参构造方法的作用

    5.有一点需要你注意一下:如何你只写了有参构造方法(初始化成员变量),没有写无参构造。这时系统不会自动添加无参构造的,此时程序会报错。 建议:构造方法都是用来初始化的,可以不写无参的构造方法,系统会默认...

    java试题及答案

    定义一个描述长方体的类Box,类中有3个整型的成员变量——length、width、和height,分别表示长方体的长、宽、高。定义构造方法,初始化这三个变量;

    Java复习题及答案

    3、所有类至少有一个构造器,构造器用来初始化类的新对象,构造器与类同名,返回类型只能为void。 ( ) 4、包是按照目录、子目录存放的,可以在程序中用package定义包,若没有package一行,则表示该文件中的类不...

    实验03 Java面向对象编程1.doc

    ○2在Student类建立构造方法初始化各域的值,并统计学生人数count; ○3创建分别获得各域(学号,姓名,性别和年龄)的public方法,以及分别设置各域(学号,姓名,性别和年龄)值的public方法(即get、set方法);...

    Java面向对象程序设计方案练习题.doc

    为MyTime类定义构造方法 以方便创建对象时初始化成员变量。 再定义diaplay方法 用于将时间信息打印出来。 为MyTime类添加以下方法 addSecond(int sec) addMinute(int min) addHour(int hou) subSecond(int sec) ...

    实验三 类的定义、封装;构造方法的定义、重载

    实验目的1、掌握类定义的方式,掌握如何在类中定义成员...4、演示如何使用有参构造方法完成对象属性的初始化。5、通过创建对象的方式演示不同构造方法的使用方式,并根据构造方法的输出结果对构造方法的重载进行学习。

    java基础非常典型的面试题目.wps

    实例变量可以在定义处或者在构造方法中被显式初始化。如果在这两处都没有初始化,那么保留自动初始化时的默认值。final型的变量必须被显式初始化。 静态变量可以在定义处或者在静态代码块中被显式初始化。如果在这两...

    Java开发技术大全(500个源代码).

    errorInit.java 演示变量初始化错误的程序 integerExample.java 演示各种整型变量的使用 isPrime.java 判断素数 leapYearByIf.java 用if语句判断闰年 leapYearByLogical.java 用逻辑表达式判断闰年 lowToUpper...

    JAVA经典继承与父类调用 geter、seter访问器 构造器

    代码中设计了各个类的基类,设置私有成员变量,利用构造器对成员变量初始化,用geter、seter访问器设置、获取成员变量的值。继承基类并创建对象,在子类中调用父类方法。

Global site tag (gtag.js) - Google Analytics