class B{}
class A{
   public A(B b){
   }
}当new一个A对象的时候,在内存上是先给A分配内存,还是先给B分配内存呢
有点迷惑

解决方案 »

  1.   

    不对的,B作为参数传递给A,A最后会得到B对象的引用,所有B一定会分配内存的,只是时间问题搞不清楚
    new A(new B());
      

  2.   

    new A(new B());
    对于这句,肯定是先 new B() 再把它作为参数传递给A,完成new A()的操作
      

  3.   

    但是这句要先执行new A,才知道了要new B的
    现在有点想明白了,在执行构造器之前,已经执行了声明语句,所以应该先给A分配的内存。再new B,再把B的引用交给A.是这样吗程序:
    class B{}
    class A{
      B b;
      public A(B b){
       this.b=b;
      }
    }
      

  4.   

    遇到这种情况可以自己做个实验咯!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");
    }
    }
      

  5.   

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

  6.   


    B b = null;new A(b);你说创建一个对象A,给A分配内存要不要给B分配内存?
      

  7.   

    编译原理第8章,display表,先给a分,再给b分。
      

  8.   

    当你执行A a=new A(new B())时候,肯定是先给B实例化,开辟堆空间,然后将其堆空间引用传给A的构造器。具体之后怎样就看你类A的定义了,如果像你一楼写的那样,当A构造器执行完后B的堆内存就自动消失了
      

  9.   

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

  10.   

    但是,初始化一个类的时候,先初始化成员变量,再执行构造器。如果类A中存在成员变量的话,就要先初始化成员变量,这时候不应该先为A分配堆空间吗。
    等到成员变量都初始化完毕以后,执行构造器之前,再为类B分配?
      

  11.   


    也说自己看过thinking in java,我就忍不住了
    reference在初始化的时候是什么值?不是null么
    这个时候跟gc有个P关系,我怒了
      

  12.   

    new A()与new B()不是一回事,不要混为一谈,new A()是创建一个A对象并分配内存,new B()是创建一个B对象并分配内存。就算A的构造方法需要一个B的对象为参数,但是B对象的内存是new B()分配的,不是new A()分配的。置于次序上,当然是先new B()再new A()了,况且8楼也说了,可以传个null进去么,那怎么会创建B对象并分配呢?
      

  13.   

    当要new一个A时,需要一个B类的对象b,所以肯定是先给B分配,然后给A分配!
      

  14.   


    同意,
    其实Java的变量是地址引用,new A() 时的申请的是放地址引用的内存。
      

  15.   

    new A的话就会产生一个A对象,对象就会占用存储空间.但是newA的时候需要一个B的引用作为参数..b要作为参数,在使用前就得赋初值,
    所以如果在new A 之前b 赋初值为null,则未创建B对象,只声明了引用,
    如果在new A之前 b 赋初值为 new B ,那么就是先B 后A了
      

  16.   

    看看字节码不就知道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:  returnnew指令 -- 在堆中为新对象分配一个足够大的内存空间。并将对象的实例变量设置为默认值。注意,这条指令并不会调用构造器进行初始化。invokespecial指令 -- 调用构造器进行初始化。我们可以看到,在堆中开辟对象空间的顺序是 先A后B,而调用构造器进行初始化的顺序是 先B后A
      

  17.   

    堆中开辟对象空间的顺序是 先A后B,而调用构造器进行初始化的顺序是 先B后A
    嗯嗯,我就是这么理解的。。
      

  18.   

    我没有把这两个混为一谈,我只是认为,在new A的时候,执行不到构造器的时候,是不会知道要new一个B的吧。而在执行构造器之前,是要先为A初始化成员变量的,所以A的内存要比B的内存先分配