首页 > 代码库 > SCJP_104——题目分析(5)

SCJP_104——题目分析(5)

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 = http://www.mamicode.com/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 = http://www.mamicode.com/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"