A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 史政法 中级黑马   /  2013-3-23 21:20  /  1673 人查看  /  6 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

new一个对象,内存中是先加载这个类的字节码文件呢?
还是先在栈内存开辟个main函数的空间呢?

点评

如果问题未解决,请继续追问回复者,如果问题已经解决,请将分类改为“已解决”,谢谢  发表于 2013-3-24 08:26

评分

参与人数 1技术分 +1 收起 理由
黄玉昆 + 1

查看全部评分

6 个回复

倒序浏览
new一个对象之前会将编译好的class文件加载到内存中这就是java的calssLoader机制,new一个java对象只是把class加载到内存,并且初始化静态变量,但是它并没有在内存中创建一个对象,说的通俗点就是他并没有执行这个类的构造方法。

评分

参与人数 1技术分 +1 收起 理由
黄玉昆 + 1

查看全部评分

回复 使用道具 举报
比如执行String str = new String();
java虚拟机会按照加载----连接----初始化的顺序执行
加载是加载String类的字节码文件,然后是连接(连接分三部:验证、准备、解析)
验证是为了保证已经加载的正确性,准备是为了静态变量分配内存,并把他初始化为默认值,解析是吧符号引用转化为直接引用。
初始化为静态变量初始化正确的值
然后才会执行构造方法

评分

参与人数 1技术分 +1 收起 理由
黄玉昆 + 1

查看全部评分

回复 使用道具 举报
先加载字节码文件
首先编译器将源文件编译成字节码文件,此时将各种方法的局部变量及操作数栈大小确定并放在字节码中,随着类一并载入方法区,
然后调用方法时通过访问方法区中的信息得到局部变量及操作数栈大小
也就是说:在将main方法压栈之前需要从方法区获取信息,而方法区的信息是随着源文件被编译成字节码时才被填充的!
希望对你有所帮助,谢谢!

评分

参与人数 1技术分 +1 收起 理由
黄玉昆 + 1

查看全部评分

回复 使用道具 举报
new一个对象,比如Person p1 = new Person(); 只要用new创建对象就会在(堆)里面开辟空间,而不是在栈里面。

评分

参与人数 1技术分 +1 收起 理由
黄玉昆 + 1

查看全部评分

回复 使用道具 举报
首先,给你纠正一个小错误,就是对象空间是存在堆内存,而栈内存中存的只是这个空间的地址值。
其次,new一个对象的时候,如果没有确切的参数,JVM是无法在堆内存中开辟空间的,道理很简单,就好比说让你建一栋大楼,但并没有给你图纸,当然是建不出来的。嘿嘿

最后,关于这类的问题,其实我们并不用太多的Java编程知识,很多时候Java是在力求让编程逻辑跟现实事物所一致,这才是编程的核心思想。

评分

参与人数 1技术分 +1 收起 理由
黄玉昆 + 1

查看全部评分

回复 使用道具 举报
陈雨 中级黑马 2013-3-24 03:41:12
7#
本帖最后由 陈雨 于 2013-3-24 03:46 编辑

以person p=new person()为例
第一步:首先判断栈内存对堆内存是否存在引用,如果存在就会加载这个person类,new的时候会将Person.class文件从硬盘通过java的JVM将这个文件加载进内存。第二步:执行静态代码块。第三步:开辟空间并在堆内存中分配内存地址。第四步:在堆中建立对象特有属性。第五步:对属性显示初始化。第六步:对对象进行构造代码块初始化。第七步对对象进行对应的构造函数的初始化。第八步:将堆内存地址付给栈内存中的p变量。

评分

参与人数 1技术分 +1 收起 理由
黄玉昆 + 1

查看全部评分

回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马