public class Test { public static void main(String[] args) {
ClassA c = new ClassA(); 
Test cm = new Test(); 
c.i=1; 
cm.revalue(c); 
System.out.println(c.i);
}
public void revalue(ClassA c) { 
ClassA d = new ClassA(); 
d.i=2; 
c=d; 
d.i=3; 

}
class ClassA { 
int i=0; 
}请帮忙解释下吧。。谢谢了

解决方案 »

  1.   

    c.i=1,所以 System.out.println出来的就是1了。
    cm.revalue(c)没有改变c的值,虽然c=d,那只是revalue内部改变了c,到外面c还是原来的c。
    你想出3,那么,
    c = cm.revalue(c);
        public ClassA revalue(ClassA c) { 
            ClassA d = new ClassA(); 
            d.i=2; 
            c=d; 
            d.i=3; 
            return c;
        } 
      

  2.   

        public void revalue(ClassA c) { 
            ClassA d = new ClassA(); 
            d.i=2; 
            c=d; 
            d.i=3; 
        } 
    这里的C 和上面的C不是同一个
    cm.revalue(c)这里主要是运行了cm的方法。
      

  3.   

    先搞清楚你所指的i是哪个对象的i,d.i=2改变的是后来new的ClassA的对象的i,而不是前面那个.
      

  4.   

    为了容易说明问题,把方法里的c改名为c2
     public void revalue(ClassA c2) { 
            ClassA d = new ClassA(); 
            d.i=2; 
            c2=d; 
            d.i=3; 
        } cm.revalue(c); 
    实际参数c和形式参数c2 不是一个东西.开始调用的时候内容一样,具有相同的值,指向同一个对象.
    但是方法里让c2=d;了,后面的修改是对c2引用的对象的修改,根c没有关系.
      

  5.   

    汗死了,拿编译器跟了半天才想清楚,public ClassA revalue(ClassA c),这句话其实是初始化了一个C引用,将参数传进去的时候,只是将外面的C引用给了内部的C引用,C=D,又将原本指向外部C所指向的地址改成了D所指的引用,所以,外部的C的指向和所指向的值其实是没变的....汗死了.......
      

  6.   

    revalue()方法只是改变了传进去的形参(引用变量c),外面的实参(引用变量c)并没有改变
    所以打印的是1
    如果想要结果不同,在revalue()方法里改变形参所引用的对象。
      

  7.   

    画下运行时实际的内存图,就很清晰了。main 中的C    public static void main(String[] args) {
            **  ClassA c = new ClassA(); 
            Test cm = new Test(); 
           **    c.i=1; 
            cm.revalue(c); 
            System.out.println(c.i);
        }
     和
        public void revalue(ClassA c) { 
            ClassA d = new ClassA(); 
            d.i=2; 
            c=d; 
            d.i=3; 
        } 
    中的C不同 
    开始时他们指向相同的对象,
    当执行c=d时,revalue方法中的C指向d所指向的对象了,而main中的C所指向的对象没有变。
    所以改变revalue方法中C所指向的对象中的I的值,对于mian中得到C不会有影响。
      

  8.   


    public class Test {    public static void main(String[] args) {
            ClassA c = new ClassA(); 
            Test cm = new Test(); 
            c.i=1; 
            cm.revalue(c); 
            System.out.println(c.i);
        }
        public void revalue(ClassA cCopy) { 
            ClassA d = new ClassA(); 
            d.i=2; 
            cCopy=d; 
            d.i=3; 
        } 
    }
    class ClassA { 
        int i=0; 
    }
    值传递 public void revalue(ClassA ccopy)这里的ccopy就是一个局部变量
    指向传递进来的c
    而之后又执行了cCopy=d;
    将cCopy重新指向d
    对cCopy的操作就和c无任何关系
      

  9.   

    非常赞同
    yirentianran
    的说法
      

  10.   

    支持8楼跟10楼的观点
    最先new 的ClassA()的引用c被拷贝了一个副本传给了revalue(ClassA c)
    此方法没有改变c 所引用的对象,只是改变了它的副本所引用的对象。
    黄飞鸿在广东开了家宝芝林,卖中药。它用同样的牌子在美国开了一家分店。
    美国宝芝林分店里不仅卖中药,还卖西药。
    那现在问你,在在广东的宝芝林里,卖的是什么药?
      

  11.   

    其实这样理解不准确,容易误导人...可以这样认为:
    你买回来一台电视机A,有一个遥控a.拿遥控a去复制一个遥控b,那么现在a b都可以控制电视机A了,但是当你
    ClassA d = new ClassA(); 
    c=d; 
    复制的遥控b只能控制电视机B(因为此时b重新指向一台新的电视机B),所以在b上做的操作只影响电视机B,而不影响电视机A.
      

  12.   

    java中,方法的参数都是值传递,所以传递进去的参数不会被改变。
      

  13.   

    按值传递,所以在mian方法C的值是不会受revalue方法影响的。
      

  14.   

    java参数传递-按值传递,即Java中传递任何东西都是传值。如果传入方法的是基本类型的东西,你就得到此基本类型的一份拷贝。如果是传递引用,就得到引用的拷贝。
    大家的几个例子~不错~不错,哈哈
      

  15.   

    java中的对象变量都是存在栈中的指向堆中具体对象的引用(相当于C的指针)。当主函数main中的对象引用c传递到方法revalue中时,其实是拷贝了一个和c一样的对象引用。在revalue中,并没有对c指向的对象进行改变,而只是把revalue中拷贝的c引用指向另外一个在revalue中创建的对象,其后还对这个新创建的对象进行了改变,但与main中的c指向的对象没有关系,而且方法运行结束后新创建的对象也会丢失。所以呢,main中的c指向的对象的属性值仍然是1,那么输出当然也是1了。
      

  16.   

    public class Test {    public static void main(String[] args) {
            ClassA c = new ClassA(); 
            Test cm = new Test(); 
            c.i=1; 
            cm.revalue(c); 
            System.out.println(c.i);//这个是对象ClassA c
        }
        public void revalue(ClassA c) { 
            ClassA d = new ClassA(); 
            d.i=2; 
            c=d; //此处你是更改的classA d与上面的无关!
            d.i=3; 
        } 
    }
    class ClassA { 
        int i=0; 
    }
      

  17.   

    只要搞清楚内存的具体的分局情况就容易理解了。
    内存的布局是这样的: 
    code segment :存放代码(比如:还没有调用的method等); 
    data segment :存放静态常量和字符串常量; 
    stack :局部变量(比如:8中基本的数据类型,引用); 
    heap : 动态申请的内存(对象)。