class Data{
public int id;
}class Util{
public void change(Data d){
d = new Data();
d.id=5;
d.id++;
}
}public class App {
public static void main(String[] args){
Data d1 = new Data();
d1.id=2;

Util u = new Util();
u.change(d1);

System.out.println(d1.id);
}}写出输出结果。在2跟6之间犹豫 结果还是写错了。
结果为2,请问该如何解释?

解决方案 »

  1.   

    因为changed()方法里有一句d = new Data(),d指向了一个新的对象,更改的是这个新对象的值,而不是dl的值
    如果没有那一句,更改的就是dl的值了
      

  2.   

    java传递的是引用。change方法里面将local变量d重新指向一个新的Data对象,就失去了对原来外部Data对象的引用,当然也无法改变其值。去掉change方法的第一句d = new Data(); local变量就一直指向外部的Data对象,结果就是6。
      

  3.   

    谈一下个人的看法。
    java里的对象其实应该是C语言里边的对象指针,指向堆内存中对象的实际地址。//---------------------------------------
    Data d1 = new Data(); //栈内存中添加一变量,堆内存中增加一对象,使栈内存值指向堆内存中对象地址
    d1.id=2;
            
    Util u = new Util();
    u.change(d1);         //将d1的地址值传给change函数的形参
            
    System.out.println(d1.id);//---------------------------------------
    public void change(Data d){
        d = new Data();   //地址指针被改了,所以操作的不是实参所指的对象了
        d.id=5;
        d.id++;
    }这类题目在C语言里边很常见,不是很难理解
      

  4.   

    这个程序的关键的一句在d = new Data()这里
    传入的参数重新生成了一个Data对象,原来的Data对象并没有改变
      

  5.   


    up
    是这个样子
    好比
    Util u = new Util();
    u.change(d1);
    形参d1先指向101房间,但是在change方法中通过new Data()后,d1指向了102房间
    但原来的Data d1中的d1还是指向101房间没变。
      

  6.   

    java中是传值引用的。在执行u.change(d1)时,在没有执行 d=new Data();这条语句之前,d的值始终为d1。你可以在
    d=new Data();之前加入System.out.println(d.id),其结果应该为2。就是因为new Data()在堆栈中新产生了一个对象,并且又把这个对象赋给了原来的d。
      

  7.   

    下次做题,吧new()全部找出来。
      

  8.   

    也就是说传入的是dl
    但是呢在change()里面却新建了一个对象dl=d
    这两个对象是同一类
    d.id=5;
    dl.id=2
    输出的是dl,不是d的id
      

  9.   

    class Util{
        public void change(Data d //这个d是一个对象句柄){
            d = new Data();//讲句柄d重新给值,原对象丢失,所以绝不可能修改传过来的对象属性
            d.id=5;
            d.id++;
        }
    }
      

  10.   


    class Data{
        public int id;
    }class Util{
        public void change(Data d){
          System.out.println("d before new"+d);
          
            d = new Data();
           System.out.println("d after new "+ d);
            d.id=5;
            d.id++;
        }
    }public class App {
        public static void main(String[] args){
            Data d1 = new Data();
            d1.id=2;
            
            Util u = new Util();
            u.change(d1);
            
            System.out.println("after exec method change d:"+d1);
            System.out.println(d1.id);
        }}
    =========================
    d before newData@126b249
    d after new Data@182f0db
    d after new : this.d1::
    after exec method change d:Data@126b249
    2------------------------
    个人直觉感觉类中的d1和方法中的d1其实是两个本身就不同的变量,或是说"变量标志"名称,虽然符号一样,但是所在范围域不一样。
    类中的d1传入后,其实这个方法根本就没操作这个参数,没有引用这个参数,当然更没有利用到。谈何在类中的对像d1会发生了改变。这里真正误导人一点其实是利用了传入参数名和新建方法体中局域变量名相同,迷惑人而已
      

  11.   


    class Data{
        public int id;
    }class Util{
        public void change(Data d){
            d = new Data();
            d.id=5;
            d.id++;
        }
    }public class App {
        public static void main(String[] args){
            Data d1 = new Data();//new了一个Data对象,假设我们叫它A,此时引用d1指向对象A
            d1.id=2;
            
            Util u = new Util();
            //调用Util类中的change方法是,你又new了一个新的Data对象的引用d,你把它也指向了d1引用所指向的对象A
            //但是在change方法中,你又new了一个新的Data对象,此时引用d又指向了新对象,然后做了一系列操作,可是都和对象A无关了
            //所以最后输出dl指向的对象A的id值还是不变的。
            u.change(d1);
            
            System.out.println(d1.id);
        }}
      

  12.   

    你的解释好像是不对的,即时你不定义新的data对象,也不会输出6,请楼主注意,change方法中并没有返回值!
      

  13.   

    只要清楚Java只有值传递就行了
    change方法的中Date d是局部变量
    方法运行完,d就销毁,根本不影响到b1
      

  14.   

    哈哈!Java方法调用中都是采用传值调用的,不支持传址调用
      

  15.   

    很显然是2.这道题出的不错,让你明白了地址传递和引用传递的区别
    d=new Data();于是d指向的是新的Data对象,接下来的操作是对新的对象的操作,不会改变原来的对象
      

  16.   

    因为changed()方法里有一句d = new Data(),d指向了一个新的对象,更改的是这个新对象的值,而不是dl的值 
    如果没有那一句,更改的就是dl的值了
    就是这样了
      

  17.   

      是哦,因为重新NEW了。。
      

  18.   

    别名现象
    调用方法时,两个引用同时指向了一个对象,在方法里面通过new()修改了方法参数的引用,而实际的引用并没有改变
      

  19.   

    挺赞成java中都是传值,没有传引用的说法的
      

  20.   

    java中的引用确实很容易搞错,内存的分析很重要啊!