关于java虚拟类的疑问,在CSDN一回帖得到很清楚的解答
1、子类在创建实例后,类初始化方法会调用父类的初始化方法(除了java.lang.Object类,因为java.lang.Object类没有父类),而这种调用会逐级追述,直到java.lang.Object的初始化方法。
这个地方我说的是初始化方法,而不是构造方法,因为构造方法是相对于java源程序而言,而编译后的class文件是初始化方法即" <init>"方法(红色部分为方法名),初始化方法是由java源程序的三个部分组成的,一个部分是成员字段后的直接的初始化语句,例如private int i=0;private Date date=new Date();等等,第二个部分是由初始化块组成,例如:
public class Test{
private int i=0;//初始化第一部分
//以下大括号内为初始化第二部分
{
this.i=4;
\\do something......
}
}
第三个部分就是java源代码中的构造方法中的代码,java源代码中有几个构造方法,那么class文件中就有几个初始化方法,编译器会把第一部分与第二部分分别复制到每个初始化方法的前端,然后把初始化方法对应参数的构造方法的代码复制到相应初始化方法中(这里说的复制其实应该说是编译,不过为了让你更好理解所以如此说).
那么说初始化方法如何追述其父类的,这也关系到初始化方法的结构,初始化方法的执行顺序以及结构就如上所说,但是每个初始化方法的第一个执行指令就是调用另外一个初始化方法,这个初始化方法可能是自身类某个初始化方法,例如你的构造函数中第一句有类似this(...)这种语句,那么初始化方法就会调用自身类的指定构造方法;如果你的构造方法中没有指定构造方法调用,那么初始化方法会默认调用父类无参数初始化方法,如果你的子类第一句为super(....),那么初始化方法会调用父类指定初始化方法。这种调用过程会递归进行调用,直到这个类是java.lang.Object类。
调用初始化方法并不代表会生成对象,你的java代码中出现new关键字加上构造方法的调用,只会生成一个对象,其父类对象不会生成,所以调用父类为抽象类的构造方法完全是合理的。而且初始化方法对于虚拟机来说只是一个名称叫做" <init>"的普通方法,区别只是生成对象以后调用而已(sun 的jdk私有包中有绕过构造方法生成对象的方式,可以证明之上说法,具体如何我这里不陈述)。
然后回答你的第二个问题,抽象类中的构造方法其实是用来给继承的子类来用的,因为构造方法相当于初始化方法,当子类调用构造方法时必须调用父类构造方法,所以你可以在子类产生对象时抽象类中按需求初始化抽象类中的字段以及执行一些初始化代码。其实并不是一定要生成某个类的实例才调用构造方法,子类也需要调用父类构造方法。而生成实例也并不一定会调用构造方法,在某些特殊实现中或者特殊情况下,生成实例不会调用构造方法。而调用了构造方法也不一定就生成了一个实例,但是那一定是一个实例调用的,就像一个普通的实例方法一样。
转自:CSDN spiniper 原文:http://topic.csdn.net/u/20090511/17/54697b7c-faa4-4491-afc1-fc97c98d28b8.html
分享到:
相关推荐
在这里,`Animal` 类具有一个构造函数来初始化动物的名字,一个 `eat()` 方法表示所有动物都能吃,以及一个纯虚函数 `makeSound()`,这要求任何继承 `Animal` 的类都必须提供自己的声音实现。 **子类的实现** `Dog...
* 指定创建派生类实例时应调用的基类构造函数,用于调用基类的构造函数完成对基类成员的初始化工作; * 在派生类中访问基类成员。 覆盖 当一个实例方法声明包含一个override限定符时,这个方法就用相同的属性覆盖...
* 类与对象的初始化过程:静态属性先初始化,然后实例化成员属性,最后调用构造方法。 * 垃圾回收机制:java 虚拟使用垃圾回收机制进行垃圾回收。 十、单例模式 * 单例模式:一个类仅仅能有一个实例。 * 构造方法...
在提供的压缩包文件`发送虚拟键值的demo`中,应该包含了实现这个功能的完整代码示例,包括`VirtualKeyView`类的源码、布局文件和对应的Activity初始化代码。通过查看和运行这个示例,开发者可以更直观地学习如何在...
- **override**:用于派生类中,覆盖基类的虚拟方法,实现多态。 - **readonly**:用于字段,使其成为只读,但可以在构造函数中初始化。需要注意的是,对于引用类型,其指向的对象仍可被修改。 - **const**:用于...
C#在初始化对象时,会按从基类到扩充类的顺序调用构造函数。如果有参数的构造函数,需要在子类中显式调用基类的构造函数。 5.2 版本控制 这部分内容可能涉及如何在代码更新时管理不同版本的类,确保兼容性和稳定性...
- 构造函数在继承中的处理遵循从基类到扩充类的顺序,先初始化基类,再初始化扩充类。 - 如果构造函数带有参数,需要在扩充类中显式调用基类的构造函数。 6. **版本控制**: - C#通过`override`、`virtual`和`...
18. Point类的拷贝初始化构造函数:应包含一个接收一个Point对象的参数,并使用这个参数初始化新对象的X、Y、Z成员。 19. 计算π的值的程序:通常使用莱布尼茨级数或其他数学方法,如马赫林级数,逐步逼近π的值。 ...
北邮Java作业的内容主要涉及到Java语言的基础知识点,包括Java的导入声明、类的继承、异常处理、数组初始化、对象创建、方法的重写以及Java虚拟机(JVM)的基本概念。以下是对北邮Java作业内容的详细知识点解析: 1. ...
静态构造函数在类型首次使用时执行,用于初始化静态成员,但不能初始化实例成员。 9. **Virtual**: 虚方法修饰符,允许子类重写父类的方法。父类提供了方法的默认实现,子类可以提供自己的实现。 10. **Override**...
总结来说,Java类的构造函数是用于创建对象并进行初始化的重要工具。构造函数重载允许我们根据不同的参数列表创建对象,以适应不同的初始化需求。了解如何正确使用构造函数和构造函数重载是编写高效、清晰Java代码的...
`out`参数在方法内部必须被初始化,即使在传递前已初始化。 11. 方法重载:通过改变参数数量或类型实现方法重载。返回值不同不能作为重载的依据。C#不支持方法默认值,通常通过重载来实现。 12. `params`关键字:...
构造函数是类中的特殊方法,用于初始化新创建的对象。Java中每个类都至少有一个构造函数,如果没有定义,编译器会自动提供一个无参构造函数。如果定义了带参数的构造函数,那么无参构造函数就不会被自动提供。构造...
静态构造函数用于初始化类的静态成员,而静态方法则由类本身而非类的实例执行。此外,C#支持方法重载,这意味着在同一类中可以定义具有相同名称但参数列表不同的多个方法,编译器会根据提供的参数选择合适的方法。 ...
根据给定的文件信息,我们可以总结出以下...以上这些知识点涵盖了面试中常见的程序输出问题,包括参数传递机制、对象成员变量的修改、类的继承与多态、类的初始化顺序等。理解这些概念对于解决实际编程问题非常有帮助。
16.4.1“最晚辈派生”类和虚基初始化 16.4.2使用缺省构造函数向虚基“警告” 16.5开销 16.6向上映射 16.7避免MI 16.8修复接口 16.9小结 16.10练习 第17章 异常处理 17.1C语言的出错处理 17.2抛出异常 17.3异常捕获 ...
static readonly 声明的是只读字段,它在运行时初始化,且同样只能初始化一次,但它可以通过类名访问。 3. extern 的含义? extern 关键字用于引入外部方法,通常用于调用操作系统API或其他非托管代码。 4. ...
5. **构造函数**:类的一种特殊成员函数,用于初始化新创建的对象。默认构造函数无需参数,自定义构造函数可以接收参数。例如: ```cpp MyClass::MyClass(int val) { x = val; } ``` 6. **析构函数**:与构造...
通过构造函数 `new_Person` 来初始化这些指针,实现了类似面向对象编程中的封装效果。 ##### 3.2 继承 虽然C语言本身不支持类的继承,但可以通过模拟的方式来实现继承的概念。这通常涉及到使用结构体和指针来维护...