通过价值/参考,什么?

时间:2012-04-24 14:58:13

标签: java methods arguments

这个程序给出6作为输出,但当我取消注释第9行时,输出为5.为什么?我认为b.a不应该改变,应该保持在主要的5。

1  class C1{
2      int a=5;

3      public static void main(String args[]){
4          C1 b=new C1();
5          m1(b);
6          System.out.println(b.a);
7      }

8      static void m1(C1 c){
9          //c=new C1();
10         c.a=6;
11    }
12 }

6 个答案:

答案 0 :(得分:10)

当您在Java中传递对象时,它们作为参考传递,意为b方法中main引用的对象和方法cm1的参数,它们都指向同一个对象,因此当您将值更改为6时,它会反映在main方法中。

现在,当您尝试执行c = new C1();时,您使c指向其他对象,但b仍然指向您在main中创建的对象因此,在main方法中看不到更新的值6,你得到5。

答案 1 :(得分:3)

您正在向方法m1传递对C1类型的Object的引用的副本。

如果您取消注释该行,您将获取该引用并将其指向其他位置(而不是原始引用仍指向第一个对象),因此,当您打印b的值时,您将打印原始对象的值,你没有改变。

这个问题有一些非常好的答案,你应该看看它。

Is Java "pass-by-reference" or "pass-by-value"?

答案 2 :(得分:3)

Java是传值,用外行术语表示当你传递一个参数时,你会创建一个指针变量的副本。对象变量应该像C中的指针一样被读取:这在某种程度上使事情更容易理解,至少在来自C世界时(其中C仅是按值传递)。

因此,在执行c=new C1()时,或者在执行c的任何分配时,您正在制作c(之前指向b的内存位置指出)指向另一个位置。 因此,以下c.a=6是对c指向的对象成员的赋值,它不再是b指向的对象。

答案 3 :(得分:1)

这是因为m1(C1 c)中的c是对象的引用,当你执行c.a = 6时,此对象中的a等于6。但是如果你在这个方法中做c = new c1(),c现在引用一个完全新的对象,那么你在这个新对象中做c.a = 6。然后,你退出方法,而另一个c对象仍然具有值5

答案 4 :(得分:1)

您的方法m1(b);在main中调用,导致在m1中创建的新实例取代已在main方法中创建的C1实例。如果在m1中注释实例化,则main中的第一个实例将生效。这是因为java对象是通过引用而不是通过值传递的。

答案 5 :(得分:1)

在Java中,除了原始类型之外,所有内容都通过引用传递,尽管它表示传递了引用的副本。

因此,在第一种情况下,指针b和c都指向同一个对象,因此更新后的值会反映在main方法中。

在第二种情况下,当你使c指向一个新对象时(通过调用new),b仍然指向在main方法中创建的对象,因此更新的值不会反映在main方法中,因为b和c指向两个不同的对象。