public class OO{
    int data;
    public OO(int i){
data=i;
    }
    public static void main(String args[]){
        OO o1 = new OO(1);
OO o2 = new OO(2);
OO o3 = new OO(3);
        o1=o3;//这句如果注释掉:打印OO@de6ced和OO@c17164(如果没注释:打印OO@de6ced和OO@de6ced)
        System.out.println(o1);
System.out.println(o3);
}
}
单独打印一个对象的话,都是OO@de6ced;注释掉那句话以后打印:o1是OO@de6ced,o3是OO@c17164。我理解为OO@de6ced这个地址先被分配。而没注释那句话打印:显然o3是OO@de6ced,却是这个地址后被分配了,这是为什么呢?
请高手指点,谢谢!!!

解决方案 »

  1.   

    new产生新对象,println(01)会自动调用o1.toString()方法,
    对象是分配在堆中的,而引用或者称为句柄是分配在栈中的,相当于指针,用来指象分配在堆中对象的
    看看C语言的指针就明白了
    o1=o3
    只是改变引用的值,也就是改变他们的指向
      

  2.   

    (1)
    指出一点打印对象输出的OO@de6ced并不是该对象的内存地址.
    这里 System.out.println(o1)方法会自动调用object类的toString()方法返回一个字符串,该字符串由类名、@ 和此对象哈希代码的无符号十六进制表示组成。
    (2) 
    引用o1起初指向new OO(1)开辟的地址空间;当o1=o3后,引用o1又指向new OO(3)开辟的地址空间.
    (3)
    一般由程序员分配的地址空间常在堆中,也就是这里的new分配的空间,它有个特点就是程序员如果不主动释放,会由OS释放;而栈由os为我们自动分配,是一块连续的内存的区域,比如你前面代码中的data o1  o3  o2等都在栈中,你可以看到他们都是局部变量。
     OO o1 = new OO(1); //指令执行的时候是两个过程:OO o1;o1=new OO(1);
      

  3.   

    两位或许没明白我的意思:
    没有o1=o3这条语句时候:System.out.println(o1); 结果:OO@de6ced
                            System.out.println(o3); 结果:OO@de6ced
                            System.out.println(o1); 
                         System.out.println(o3);结果:OO@de6ced
                                                              OO@c17164
    通过上面的结果,我预计加上o1=o3这句语句之后:
                            System.out.println(o1); 
                         System.out.println(o3);结果为:OO@c17164
                                                        OO@c17164
    可实际结果却是:OO@de6ced
                  OO@de6ced不明白OO@de6ced和OO@c17164为什么是这样的顺序??
      

  4.   

    我再次拿出我回复中的第一条 : 
     指出一点打印对象输出的OO@de6ced并不是该对象的内存地址. 
    这里 System.out.println(o1)方法会自动调用object类的toString()方法返回一个字符串,该字符串由类名、@ 和此对象哈希代码的无符号十六进制表示组成。 

      (1) hash发生在执行toString()的时候,而不是在分配地址的时候。不要老是想着OO@de6ced是个地址!
      public class OO{ 
        int data; 
        public OO(int i){ 
    data=i; 
        } 
        public static void main(String args[]){ 
            OO o1 = new OO(1); 
    OO o2 = new OO(2); 
    OO o3 = new OO(3); 
     System.out.println(O3); //这里先打印O3


    打印的结果仍然是OO@de6ced。
    (2)为什么是OO@de6ced?
         当然我无法给你hash函数,我只是再次补充“该字符串由类名、@ 和此对象哈希代码的无符号十六进制表示组成”这点。
         前面已经讲到toString()方法返回String类型,而你打印的是OO类型,它肯定要类型转换(OO---->String),它的转换方式是 getClass().getName() + '@' + Integer.toHexString(hashCode());
    。[/color]
    (3)您的帖子O分,回答您的问题心情沉重啊!