代码如下:
class BirthDate{
private int day;
private int month;
private int year;
public BirthDate(int d,int m,int y){
day = d;
month = m;
year = y;
}

public void display(){
System.out.println(year+"-"+month+"-"+day);
}

public  void change(BirthDate b){
b = new BirthDate(2,23,1988);
}
}public class Testb{
public static void main(String args[]){
BirthDate d1 = new BirthDate(2,23,1990);
d1.change(d1);
d1.display();
}

}我想问的是为什么di.change里面的内存空间是如何分配如何运行的。d1在栈中,d1的值是一个地址(是什么地址呢?视频上说是非物理地址,但这个东西能找到堆中new出来的对象,姑且叫它作地址吧)把d1的值copy给b,再new一个BirthDate对象,让b指向它??也就是的b,即d1的值,也就是d1的地址指向该对象,那为何值没改变??
视频上的理解是,new出一个对象,该对象在堆中有另一个地址,b指向该地址,也就是b的值变了
请问我的理解错误在哪里了,不是类似于c语言的指针吗???求解。

解决方案 »

  1.   

    补充:视频上的理解是,new出一个对象,该对象在堆中有另一个地址,b指向该地址,也就是b的值变了d1的值没变。
    请问我的理解错误在哪里了,不是类似于c语言的指针吗???求解。
      

  2.   

    直观的和LZ说吧首先有d1这个对象然后调用d1.change(d1);此时有一个引用b指向d1这个对象的地址然后在change方法调用时,又new了一个对象,并且让b指向了这个对象于是我们发现,d1其实一点变动都没有
      

  3.   

    d1在栈中,d1的值是一个地址(是什么地址呢?视频上说是非物理地址,但这个东西能找到堆中new出来的对象,姑且叫它作地址吧)
    这里的理解没问题,非物理地址是说是个逻辑地址,也就是一个相对地址,不是绝对地址
    把d1的值copy给b,再new一个BirthDate对象,让b指向它??也就是的b,即d1的值,也就是d1的地址指向该对象,那为何值没改变??
    这里的理解有误(后半部分有误),首先每个方法有个方法栈,每个栈的参数和变量是属于自己的栈,和其他栈无关,所以main的d1和change的b是各自方法栈的变量,也就是d1和b不是同一个变量,只是他们的值相同,即在方法调用的时候,把d1的值复制b,所以在change方法中,把b的指向改变,让它引用new出来的一个新的对象,这个跟d1毫无关系,d1的值还是原来的对象的地址视频上的理解是,new出一个对象,该对象在堆中有另一个地址,b指向该地址,也就是b的值变了
    这里的理解是对的,b的指向变了,也就是b的值变了,但是上面说了,d1和b不是同一个变量,因为在不同的栈,只是他们的值相同而已,所以d1的值根本就没有发生过改变请问我的理解错误在哪里了,不是类似于c语言的指针吗???求解。
    这确实类似于C的指针,但是LZ对C指针也没理解好,C语言也一样,改变方法内部指针的指向,不影响方法外部的指针,原因同上。举个C的例子void main() {
        int i=0;
        int* p = &i;
        change(p);
        printf("%d", *p);
    }void change(int *p) { //很明显,这里的p和上面的p不是同一个,否则就重名了,
        int k=10;           //所以属于不同的栈的,也就是作用域在不同的栈
        //*p = 10; //这样是可以引起外部的p的指向的内容发生变换,因为这里的p和mai的p指向相同,
                    //它修改的是p指向的地址里的内容
        p = &k; //改变change的p的指向,不影响main的p的指向,注意这里和上面的区别
    }
      

  4.   


    额,我的理解是这样的,
    public  void change(BirthDate b)
    {
         b = new BirthDate(2,23,1988);
    }
    方法里改变的是b的值,但java是值传递,b的值没有改变(内容当然也没变),
    就像C语言里以下使用时改变不了b的值以及其中内容的,改变内容可以直接 *b = c;  但java中没有指针void change(int *b)
    {
      int c = 5;
      b = &c;       
    }  
      

  5.   

    不知道LZ怎么理解我说的。方法里改变的是b的值,但java是值传递,b的值没有改变(内容当然也没变),
    你都让b指向新的地址了,b的值怎么会没变呢?b的值变了,但是d1的值没变就像C语言里以下使用时改变不了b的值以及其中内容的,改变内容可以直接 *b = c; 但java中没有指针void change(int *b)
    {
      int c = 5;
      b = &c;   //这里可以改变b的指向,除非你参数用了const,但是这个b是属于change方法栈的,
                  //所以它不能改变change外部方法栈的和b指向同一个地址的指针的指向
    } C的b=&c,和java的b=new XXX的意思是一样的,都是改变b的值,让它指向以一个新的地址
    上面也说了,栈和栈是不一样的,所以栈内的变量是不一样的,所以b虽然改变了,外部的和b原来指向同一个地址的变量的值没变,因为change栈根本没法直接操作栈外的变量,可以修改栈外变量指向的地址的内容,但是绝对做不到改变栈外变量的指向,因为它没法拿到栈外变量本身的地址
      

  6.   

    大致明白你说的。b和d1值相同,逻辑地址不同。所以,new出一个对象出来,让该对象逻辑地址指向b,只是把逻辑地址的值赋给了b,,方法调用完毕,b消失。与d1无关。感谢详细说明,让我更加明白了