18.
public class Test { public static void add3(Integer i) { int val=i.intvalue(); val+=3; i=new Integer(val); } public static void main(String args[]) { Integer i=new Integer(0); add3(i); System.out.println(i.intvalue()); } }
what is the result? b
A. compile fail B.print out "0" C.print out "3"
D.compile succeded but exception at line 3
这里考察的是 Java 中的值传递
在 Java 中,方法的参数的传递究竟是按值传递还是按引用传递,一直以来都是有争论的。争论的原因是因为 Java 中有两种数据类型,一种是基本数据类型,一种是引用数据类型。
先讲基本数据类型的参数传递。与 C 语言不同,将实际参数传递给方法后,对参数的改变不会影响到原来的参数。这是因为 Java 传递的是原来参数的拷贝,不会影响到原来的数值。
比如下面的例子
1 public class Test 2 { 3 public int value = 0; 4 5 public void add3(int value) 6 { 7 value++; 8 } 9 10 public static void main(String[] args) 11 { 12 Test test = new Test(); 13 System.out.println("value 的初始值为 " + test.value); 14 15 System.out.println("调用 add3 方法后"); 16 test.add3(test.value); 17 System.out.println("value 的值为 " + test.value); 18 } 19 }
输出结果为
value 的初始值为 0
调用 add3 方法后
value 的值为 0
接着说引用数据类型。引用数据类型变量存放的是内存地址,将引用变量拷贝一份传入方法内部,那么方法内部的变量和方法外部的变量指向的是同一个内存地址。方法内部做出的改变可能会影响到外部的数值。
将上面的例子改一下,传入Test对象的引用,如下
1 public class Test 2 { 3 public int value = 0; 4 5 public void add3(Test t) 6 { 7 t.value++; 8 } 9 10 public static void main(String[] args) 11 { 12 Test test = new Test(); 13 System.out.println("value 的初始值为 " + test.value); 14 15 System.out.println("调用 add3 方法后"); 16 test.add3(test); 17 System.out.println("value 的值为 " + test.value); 18 } 19 }
输出结果为:
value 的初始值为 0
调用 add3 方法后
value 的值为 1
但是,如果传入的引用不再指着原来的对象,而是转而指向了别的对象,外部的对象不会也随着指向另外的对象,因为 Java 是值传递的,传入的是值的拷贝。
题目的例子就是这样:
1 public class Test 2 { 3 public static void add3(Integer i) 4 { 5 int val=i.intvalue(); 6 val+=3; 7 i=new Integer(val); 8 } 9 10 public static void main(String args[]) 11 { 12 Integer i=new Integer(0); 13 add3(i); 14 System.out.println(i.intvalue()); 15 } 16 }
i 指向 Integer 的对象,拷贝一份 i 传入方法后,就有两个 i 指向 Integer 对象,在方法内对 i 的属性的改变会影响到方法外部。
i = new Integer(val) 这句话创建了一个新的 Integer 对象,这时候方法内的 i 不再指向原来的 Integer 对象,而是指向新的 Integer 对象,而方法外部的 i 还是指向原来的 Integer 对象。
所以正确答案很明显了 B:print out "0"