java中的对象创建过程
2014-03-20 17:57
567 查看
最近面试中,有一个问题,java中使用new创建一个对象的时候,详细的过程是怎么样的。
当时还真被问住了,一直做开发没深究其中的原理。这几天看了下java编程思想中的第五章和第七章,大致了解了下。
首先看一个类Dog:
Java代码
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方法中代码是newDog()时,程序的输出结果,:
Java代码
DogProfile构造方法
Dog的静态代码区域
Dog的名字是:京巴
当main方法中代码是Dog.doSomething()时,程序输出结果是:
Java代码
DogProfile构造方法
Dog的静态代码区域
执行Dog类中的静态方法 doSomething()方法
当main方法中代码是System.out.println(Dog.profile)时,程序输出结果是:
Java代码
DogProfile构造方法
Dog的静态代码区域
Dog的雌雄是:公,年龄是:3
Dog类中我分别设置了一个普通的属性和一个静态属性,同时类中还存在一个static 代码区域,通过分析程序的结果,我们可以大致了解了对象的创建过程:
1.所有的类都是在对其第一次使用时,动态加载到JVM中。当首次创建类型为Dog的对象时,或者Dog类的静态方法,静态属性域首次被访问时,java解释器查找classPath,定位到Dog.class文件
2.载入Dog.class文件,生成一个Class类型对象,所有有关的静态初始化动作都会执行,静态代码块,静态成员属性。并且这种初始化动作只在Class对象首次加载时候进行一次。
3. 当用newDog()创建对象时,首先JVM在堆heap上为Dog对象分
4000
配足够的存储空间
4.存储空间清空,自动将Dog对象中的所有基本类型数据都设置成了默认值,对象引用被设置为null
5. 执行所有在字段定义处的一些初始化操作
6. 调用构造器方法。(没有继承)
如此一来,便创建了这个对象.
以上是不存在继承的情况下的执行过程,如果是存在多重继承的情况下呢?
首先看代码:
Java代码
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对象,程序输出是:
Java代码
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编程思想中的第五章和第七章,大致了解了下。
首先看一个类Dog:
Java代码
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方法中代码是newDog()时,程序的输出结果,:
Java代码
DogProfile构造方法
Dog的静态代码区域
Dog的名字是:京巴
当main方法中代码是Dog.doSomething()时,程序输出结果是:
Java代码
DogProfile构造方法
Dog的静态代码区域
执行Dog类中的静态方法 doSomething()方法
当main方法中代码是System.out.println(Dog.profile)时,程序输出结果是:
Java代码
DogProfile构造方法
Dog的静态代码区域
Dog的雌雄是:公,年龄是:3
Dog类中我分别设置了一个普通的属性和一个静态属性,同时类中还存在一个static 代码区域,通过分析程序的结果,我们可以大致了解了对象的创建过程:
1.所有的类都是在对其第一次使用时,动态加载到JVM中。当首次创建类型为Dog的对象时,或者Dog类的静态方法,静态属性域首次被访问时,java解释器查找classPath,定位到Dog.class文件
2.载入Dog.class文件,生成一个Class类型对象,所有有关的静态初始化动作都会执行,静态代码块,静态成员属性。并且这种初始化动作只在Class对象首次加载时候进行一次。
3. 当用newDog()创建对象时,首先JVM在堆heap上为Dog对象分
4000
配足够的存储空间
4.存储空间清空,自动将Dog对象中的所有基本类型数据都设置成了默认值,对象引用被设置为null
5. 执行所有在字段定义处的一些初始化操作
6. 调用构造器方法。(没有继承)
如此一来,便创建了这个对象.
以上是不存在继承的情况下的执行过程,如果是存在多重继承的情况下呢?
首先看代码:
Java代码
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对象,程序输出是:
Java代码
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内存区域模型、对象创建过程、常见OOM
- java中的对象创建过程
- 深入理解JVM : Java堆中对象创建、布局、访问全过程
- java对象创建过程
- 深入理解java对象的创建过程,类的初始化与实例化
- java 程序加载过程---3--类中申明同时申明类的静态对象 创建类的实例 访问类的静态变量 调用类的静态方法 使用反射方法 初始化类的子类对象 直接使用java.exe 调用某个类
- (转载)JAVA中对象创建和初始化过程
- 面试总结之Java中创建对象过程及方式
- 深入理解Java对象的创建过程:类的初始化与实例化
- Java对象创建的过程
- java内存结构和对象创建的过程
- 《Thinking in Java》——静态、非静态成员变量、子句的初始化顺序(含继承)及对象创建过程
- 【Java基础】对象的具体创建过程
- java 程序加载过程---2-创建类实例对象
- java对象的创建过程
- Java:对象创建和初始化过程
- java对象创建的过程总结
- Java对象的创建过程
- Java对象创建过程补遗