一个简单的内存分配问题

jessewizard 2010-07-19 09:34:44
class B{}
class A{
public A(B b){
}
}

当new一个A对象的时候,在内存上是先给A分配内存,还是先给B分配内存呢
有点迷惑
...全文
190 24 打赏 收藏 转发到动态 举报
写回复
用AI写文章
24 条回复
切换为时间正序
请发表友善的回复…
发表回复
jessewizard 2010-07-23
  • 打赏
  • 举报
回复
[Quote=引用 17 楼 spiniper 的回复:]

new A()与new B()不是一回事,不要混为一谈,new A()是创建一个A对象并分配内存,new B()是创建一个B对象并分配内存。就算A的构造方法需要一个B的对象为参数,但是B对象的内存是new B()分配的,不是new A()分配的。置于次序上,当然是先new B()再new A()了,况且8楼也说了,可以传个null进去么,那怎么会创建B对象并分配呢?
[/Quote]
我没有把这两个混为一谈,我只是认为,在new A的时候,执行不到构造器的时候,是不会知道要new一个B的吧。而在执行构造器之前,是要先为A初始化成员变量的,所以A的内存要比B的内存先分配
jessewizard 2010-07-23
  • 打赏
  • 举报
回复
[Quote=引用 22 楼 heartraid86 的回复:]

看看字节码不就知道JVM如何运行的吗?

Java code

public class Test {
public static void main(String[] args){
new A(new B());
}
}




0: new #13; //#13 是常量池中class A的CONSTANT_Class_info的常量表入口……
[/Quote]
堆中开辟对象空间的顺序是 先A后B,而调用构造器进行初始化的顺序是 先B后A
嗯嗯,我就是这么理解的。。
heartraid86 2010-07-22
  • 打赏
  • 举报
回复
看看字节码不就知道JVM如何运行的吗?


public class Test {
public static void main(String[] args){
new A(new B());
}
}



0: new #13; //#13 是常量池中class A的CONSTANT_Class_info的常量表入口地址
3: new #15; //#15 同上 class B
6: dup
7: invokespecial #17; //Method B."<init>":()V
10: invokespecial #18; //Method A."<init>":(LB;)V
13: return

new指令 -- 在堆中为新对象分配一个足够大的内存空间。并将对象的实例变量设置为默认值。注意,这条指令并不会调用构造器进行初始化。

invokespecial指令 -- 调用构造器进行初始化。

我们可以看到,在堆中开辟对象空间的顺序是 先A后B,而调用构造器进行初始化的顺序是 先B后A
浪漫江湖 2010-07-22
  • 打赏
  • 举报
回复
我同意11楼的说法
木桶爸爸 2010-07-22
  • 打赏
  • 举报
回复
new A的话就会产生一个A对象,对象就会占用存储空间.但是newA的时候需要一个B的引用作为参数..b要作为参数,在使用前就得赋初值,
所以如果在new A 之前b 赋初值为null,则未创建B对象,只声明了引用,
如果在new A之前 b 赋初值为 new B ,那么就是先B 后A了
laboss 2010-07-22
  • 打赏
  • 举报
回复
[Quote=引用 17 楼 spiniper 的回复:]
new A()与new B()不是一回事,不要混为一谈,new A()是创建一个A对象并分配内存,new B()是创建一个B对象并分配内存。就算A的构造方法需要一个B的对象为参数,但是B对象的内存是new B()分配的,不是new A()分配的。置于次序上,当然是先new B()再new A()了,况且8楼也说了,可以传个null进去么,那怎么会创建B对象并分配呢?
[/Quote]

同意,
其实Java的变量是地址引用,new A() 时的申请的是放地址引用的内存。。。。
茫茫大海 2010-07-21
  • 打赏
  • 举报
回复
当要new一个A时,需要一个B类的对象b,所以肯定是先给B分配,然后给A分配!
树成 2010-07-21
  • 打赏
  • 举报
回复
new A()与new B()不是一回事,不要混为一谈,new A()是创建一个A对象并分配内存,new B()是创建一个B对象并分配内存。就算A的构造方法需要一个B的对象为参数,但是B对象的内存是new B()分配的,不是new A()分配的。置于次序上,当然是先new B()再new A()了,况且8楼也说了,可以传个null进去么,那怎么会创建B对象并分配呢?
nihuajie05 2010-07-21
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 jessewizard 的回复:]

引用 14 楼 zhaozhenfei444 的回复:

我来详细说下mojunbin的意思:
首先在执行A的构造函数之前,对A构造函数之前传入的参数最先被初始化(在think in java中是这样描述的:所有变量在函数使用它之前被初始化)这样B先分配堆空间,分配之后,垃圾回收启动,B没有被使用,于是又回收了

但是,初始化一个类的时候,先初始化成员变量,再执行构造器。如果类A中存在……
[/Quote]

也说自己看过thinking in java,我就忍不住了
reference在初始化的时候是什么值?不是null么
这个时候跟gc有个P关系,我怒了
jessewizard 2010-07-20
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 cl61917380 的回复:]

遇到这种情况可以自己做个实验咯!
Java code

public class newAB
{
public newAB(B b){
System.out.println("A");
}
public static void main(String[] args)
{
new newAB(new B());
……
[/Quote]
这个程序很明显是 B A ,我想问的是,在堆内存的分配上,是先给A 还是先给B分配的,构造器是测不出来的
内存分配是在构造器前还是后还是中?
acj14591 2010-07-20
  • 打赏
  • 举报
回复
6楼明显是正解
wangfeiwoyun 2010-07-20
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 jessewizard 的回复:]

这个程序很明显是 B A ,我想问的是,在堆内存的分配上,是先给A 还是先给B分配的,构造器是测不出来的
内存分配是在构造器前还是后还是中?
[/Quote]

B b = null;

new A(b);

你说创建一个对象A,给A分配内存要不要给B分配内存?
jessewizard 2010-07-20
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 zhaozhenfei444 的回复:]

我来详细说下mojunbin的意思:
首先在执行A的构造函数之前,对A构造函数之前传入的参数最先被初始化(在think in java中是这样描述的:所有变量在函数使用它之前被初始化)这样B先分配堆空间,分配之后,垃圾回收启动,B没有被使用,于是又回收了
[/Quote]
但是,初始化一个类的时候,先初始化成员变量,再执行构造器。如果类A中存在成员变量的话,就要先初始化成员变量,这时候不应该先为A分配堆空间吗。
等到成员变量都初始化完毕以后,执行构造器之前,再为类B分配?
zhaozhenfei444 2010-07-20
  • 打赏
  • 举报
回复
我来详细说下mojunbin的意思:
首先在执行A的构造函数之前,对A构造函数之前传入的参数最先被初始化(在think in java中是这样描述的:所有变量在函数使用它之前被初始化)这样B先分配堆空间,分配之后,垃圾回收启动,B没有被使用,于是又回收了
zhaozhenfei444 2010-07-20
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 mojunbin 的回复:]
当你执行A a=new A(new B())时候,肯定是先给B实例化,开辟堆空间,然后将其堆空间引用传给A的构造器。具体之后怎样就看你类A的定义了,如果像你一楼写的那样,当A构造器执行完后B的堆内存就自动消失了
[/Quote]
十分同意这位仁兄的说法。
hjjk123 2010-07-20
  • 打赏
  • 举报
回复
帮顶吧...........
avalon 2010-07-20
  • 打赏
  • 举报
回复
当你执行A a=new A(new B())时候,肯定是先给B实例化,开辟堆空间,然后将其堆空间引用传给A的构造器。具体之后怎样就看你类A的定义了,如果像你一楼写的那样,当A构造器执行完后B的堆内存就自动消失了
ganyiboy 2010-07-20
  • 打赏
  • 举报
回复
编译原理第8章,display表,先给a分,再给b分。
coooliang 2010-07-19
  • 打赏
  • 举报
回复
遇到这种情况可以自己做个实验咯!

public class newAB
{
public newAB(B b){
System.out.println("A");
}
public static void main(String[] args)
{
new newAB(new B());
//打印出 B A
}
}
class B{
public B(){
System.out.println("B");
}
}
jessewizard 2010-07-19
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 cntmi 的回复:]

new A(new B());
对于这句,肯定是先 new B() 再把它作为参数传递给A,完成new A()的操作
[/Quote]
但是这句要先执行new A,才知道了要new B的
现在有点想明白了,在执行构造器之前,已经执行了声明语句,所以应该先给A分配的内存。再new B,再把B的引用交给A.是这样吗

程序:
class B{}
class A{
B b;
public A(B b){
this.b=b;
}
}
加载更多回复(4)

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧