java中的对象创建过程
来源:互联网 发布:java 更改数据库 编辑:程序博客网 时间:2024/06/05 06:13
今天在网上查new一个对象时的执行过程的时候,想知道为什么在写了一个有参数的构造方法时,默认的无参构造就没有了,需要手动加一个,却以外查到了这个,觉得有用,放上来一起学习。
原文地址:http://blog.sina.com.cn/s/blog_687ab1d70100r9gv.html
最近面试中,有一个问题,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(); -
} - }
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的名字是:京巴
DogProfile构造方法Dog的静态代码区域Dog的名字是:京巴
- DogProfile构造方法
- Dog的静态代码区域
- 执行Dog类中的静态方法
doSomething()方法
DogProfile构造方法Dog的静态代码区域执行Dog类中的静态方法 doSomething()方法
- DogProfile构造方法
- Dog的静态代码区域
- Dog的雌雄是:公,年龄是:3
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("不知名"); -
-
} - }
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的名字是:不知名
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创建对象过程
- Java对象创建过程
- JAVA 对象创建过程
- Java对象创建过程
- Java对象创建过程
- Java对象创建过程
- java对象创建过程
- java对象创建过程
- java对象创建过程
- Java对象在Java虚拟机中的创建过程
- 解析Java中创建String对象过程中的内存分配
- [自学问题总结] java中的对象创建过程
- 二维数组中的查找
- JS 如何将 HTML 页面导出为多页 PDF
- 复杂链表的复制
- Vue+WebPack+HBuilder 项目记录
- Ubuntu跑分
- java中的对象创建过程
- AS创建assets文件夹与字体
- java创建子线程为什么要有两种方法?
- tomcat启动startup闪退bat解决方案
- java验证手机号
- lintcode二叉树的后序遍历
- opencv检测圆
- Top 命令详解
- 几种Windows进程通信