最近面试中,有一个问题,java中使用new创建一个对象的时候,详细的过程是怎么样的。
当时还真被问住了,一直做开发没深究其中的原理。 这几天看了下java编程思想中的第五章和第七章,大致了解了下。
首先看一个类Dog:
package cn.tutorinfo.classloader;
public class Dog {
private String name;
// 静态成员变量
private static DogProfile profile = new DogProfile("公", 3);
// 静态代码块
static {
System.out.println("Dog的静态代码区域");
}
// 静态方法
public static void doSomething() {
System.out.println("执行Dog类中的静态方法 doSomething()方法");
}
// 构造方法
Dog(String name) {
this.name = name;
System.out.println("Dog的名字是:" + name);
}
public static void main(String[] args) {
new Dog("京巴");
// Dog.doSomething();
// System.out.println(Dog.profile);
}
}
class DogProfile {
private String male;
private Integer age;
DogProfile(String male, Integer age) {
this.male = male;
this.age = age;
System.out.println("DogProfile构造方法");
}
@Override
public String toString() {
return new StringBuilder("Dog的雌雄是:").append(this.male).append(",年龄是:").append(this.age).toString();
}
}
当 main方法中代码是new Dog()时,程序的输出结果,:
DogProfile构造方法
Dog的静态代码区域
Dog的名字是:京巴
当main方法中代码是Dog.doSomething()时,程序输出结果是:
DogProfile构造方法
Dog的静态代码区域
执行Dog类中的静态方法 doSomething()方法
当main方法中代码是System.out.println(Dog.profile) 时,程序输出结果是:
DogProfile构造方法
Dog的静态代码区域
Dog的雌雄是:公,年龄是:3
Dog类中我分别设置了一个普通的属性和一个静态属性,同时类中还存在一个static 代码区域,通过分析程序的结果,我们可以大致了解了对象的创建过程:
1. 所有的类都是在对其第一次使用时,动态加载到JVM中。当首次创建类型为Dog的对象时,或者Dog类的静态方法,静态属性域首次被访问时,java解释器查找classPath,定位到Dog.class文件
2. 载入Dog.class文件,生成一个Class类型对象,所有有关的静态初始化动作都会执行,静态代码块,静态成员属性。 并且这种初始化动作只在Class对象首次加载时候进行一次。
3. 当用new Dog()创建对象时,首先JVM在堆heap上为Dog对象分配足够的存储空间
4. 存储空间清空,自动将Dog对象中的所有基本类型数据都设置成了默认值,对象引用被设置为null
5. 执行所有在字段定义处的一些初始化操作
6. 调用构造器方法。(没有继承)
如此一来,便创建了这个对象.
以上是不存在继承的情况下的执行过程,如果是存在多重继承的情况下呢?
首先看代码:
package cn.tutorinfo.classloader;
class DogProfile {
private String male;
private Integer age;
DogProfile(String male, Integer age) {
this.male = male;
this.age = age;
System.out.println("DogProfile构造方法");
}
@Override
public String toString() {
return new StringBuilder("Dog的雌雄是:").append(this.male).append(",年龄是:").append(this.age).toString();
}
}
class Dog {
private String name;
// 静态成员变量
private static DogProfile profile = new DogProfile("公", 3);
// 静态代码块
static {
System.out.println("Dog的静态代码区域");
}
// 静态方法
public static void doSomething() {
System.out.println("执行Dog类中的静态方法 doSomething()方法");
}
// 构造方法
Dog(String name) {
this.name = name;
System.out.println("Dog的名字是:" + name);
}
}
class JingbaDog extends Dog {
private static DogProfile profile = new DogProfile("母", 2);
JingbaDog(String name) {
super(name);
System.out.println("JingbaDog的名字是:" + name);
}
}
public class DogExamp extends JingbaDog {
private static DogProfile profile = new DogProfile("母", 1);
DogExamp(String name) {
super(name);
System.out.println("DogExamp的名字是:" + name);
}
//生成一个DogExamp对象
public static void main(String[] args) {
new DogExamp("不知名");
}
}
main方法中就只生成一个DogExamp对象,程序输出是:
1. DogProfile构造方法
2. Dog的静态代码区域
3. DogProfile构造方法
4. DogProfile构造方法
5. Dog的名字是:不知名
6. JingbaDog的名字是:不知名
7. DogExamp的名字是:不知名
我们结合没有继承的情况下的流程,以及上述的结果分析下:
java解释器在类路径中查找DogExamp.class文件后,会根据继承规则,定位JiingbaDog.class 和Dog.class. 分别载入后生成相应的Class对象,此时按照上述的流程,依次执行静态初始化的动作.
首先在Dog类中执行静态初始化,在初始化静态属性profile时,导致实例化Dogprofile对象,输出第一行。然后执行静态代码块,导致输出第二行。
接下来,子类JingbaDog中执行静态初始化动作,同样初始化了profile静态属性,导致实例化DogProfile对象,输出第三行,同理,DogExamp中的静态成员初始化,输出第4行。
静态初始化结束后,按照类的继承关系的构造方法的调用,首先执行基类Dog的构造方法,输出第5行
然后执行JingbaDog的构造方法,输出第6行。
最后执行自身的构造方法 输出第7行.
根据以上分析,我们得出的结论是:
1. 当首次创建一个类的对象时(此时即是调用构造方法,构造方法也是隐式的静态),或者类的静态方法被调用,静态成员属性被引用时,java解释器都将查找类对象的class文件
2. 载入class文件后生成Class对象时,会执行静态初始化所有动作。(包括父类的静态成员和静态代码块)
3. 执行类定义在字段处的初始化动作
4. 递归调用构造器执行构造方法
....
分享到:
相关推荐
详细介绍java对象的创建过程,以致对java基础详细的掌握!
Java对象的创建过程结合反射进行解析。
介绍java对象的创建、初始化、和引用。并分析一下JAVA中对象创建和初始化过程中涉及的相关概念问题。
浅析Java语言中对象的创建过程
浅析Java语言中对象的创建过程.pdf
* 执行启动类的main函数 -> 创建对象的继承树从高到底的类层次中的静态块(如果已经被执行过,则不会重复执行) -> * 继承树中的从最高层开始的实例语句块{}、然后对应的构造函数、以及构造函数中调用的方法 * ...
讲述了java对象创建的详细过程,涉及到内存中是如何存储的,以及垃圾回收方式
本次实验进一步学习了Java的相关知识,深入理解了面向过程与面向对象语言的区别,了解了面向对象语言的三大特征,掌握类的声明和构造方法,掌握了对象的创建方法与创建机制,掌握了成员变量、类变量和局部变量区别,...
内容概要: 本文详细演示了如何在Java中创建对象并使用...建议通过创建简单的Java项目和类,并编写、运行和调试代码来加深对对象创建和使用的理解。 如有疑问,可以参考Java官方文档或搜索相关资料,进一步扩展学习。
申请内存,在堆里面创建一个新对象。 半初始化,新建对象中的m值是0。 dup 复制操作,因为invokespecial会消耗一份引用,所以先复制一份 invokespecial 4 invokespecial #3 init是调用它的构造方法。 此时对象中的m...
下面小编就为大家带来一篇浅谈Java内存区域与对象创建过程。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
面向对象和面向过程的区别 成员变量与局部变量的区别 创建一个对象用什么运算符?对象实体与对象引用有何不同? 对象的相等和引用相等的区别 类的构造方法的作用是什么? 如果一个类没有声明构造方法,该程序能正确执行...
主要介绍了从汇编码分析java对象的创建过程,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
在对象的创建阶段,Java对象实体类会根据预设的属性字段和初始值进行初始化。这些属性字段通常定义在类的声明中,并使用关键字进行描述。在实例化一个对象时,Java虚拟机会根据类的定义分配相应的内存空间,并将属性...
内容概要: 本文档详细介绍了Java编程中对象的创建和使用,并对对象在内存中的分配和使用进行了详细分析。通过示例代码和详细解释,帮助读者理解对象的创建过程、内存分配和使用方法。 能学到什么: 理解对象的...
Java面向对象 1 1 学习方法与要求 1 2 面向对象语言与面向过程语言的区别 7 3 面向对象?什么对象? 8 4 什么是类? 9 5 如何创建一个类Class? 10 6 如何使用类创建对象 10 7 引用与实例 11 8 实例属性与实例方法 ...
描述对象的创建过程,对象的内存布局,jvm指针压缩,对象访问
1面向对象编程与面向过程编程的比较 2类与对象的关系 3类的组成 4对象的创建与使用 5多个源文件的编译
但是在编写过程中需要遵循另一个重要的面向对象设计原则:继承。 《Java程序设计案例教程》教学课件05深入Java面向对象全文共47页,当前为第4页。 5.2 继承 继承可以充分利用现有的代码,解决编程过程中代码冗余的...
8.1 Java对象在JVM中的生命周期 8.2 理解Session的缓存 8.2.1 Session的缓存的作用 8.2.2 脏检查及清理缓存的机制 8.3 Java对象在Hibernate持久化层的状态 8.3.1 临时对象的特征 8.3.2 持久化对象的...