2011-04-13 65 views
0


在下面的代码为什么引用字符串的行为不像其他对象引用?

public class Test { 

    public static void main(String[] args){ 
     int [] arr = new int[]{1,2}; 
     String b=new String("abc"); 
     f(b,arr); 
     System.out.println(b); 
     System.out.println(arr[0]); 

    } 

    public static void f(String b, int[] arr){ 

     b+="de"; 
     b=null; 
     arr[0] = 5; 
    } 
} 

为什么字符串的参考变量不表现得像阵列的参考变量?
我知道字符串是不可变的,因此对它们的操作会创建新的字符串,但是如何引用字符串以及引用b如何引用旧值,尽管它已更改为引用f()方法中的其他内容。

+1

引用字符串就表现得像其他引用。尝试将'f'的参数重命名为'x'和'y'并在'f'内部执行'y = null;'而不是'arr [0] = 5;'并且您可能会理解它。 – 2011-04-13 17:20:17

+0

你的代码中有两个不同的'b'变量,而不仅仅是一个。 – MeBigFatGuy 2011-04-13 17:29:13

回答

7

Java中的对象引用是按值传递的。赋值只是改变了值,并不会改变原来的对象引用。

在您的例子arr[0]改变,但尽量arr=null,你会看到它有没有效果的方法返回之后。

1

方法调用在Java中被值调用,关于这个问题还有很长时间的争论,但是我认为我们应该考虑Java的实现语言C/C++。对象引用只是指向对象的指针,而基元是值。每当调用某个方法时,实际参数都会被复制到形式参数中。因此,如果您将指针更改为引用另一个对象,则原始指针不受此更改的影响,但如果您更改了对象本身,则主叫方也可以看到更改,因为双方都指的是同一对象。

,在你的例子中,你正在将被调用的方法中的字符串引用改为null,但是你正在改变被数组引用引用的对象。这两个操作是不一样的,因此它们有不同的后果。例如,如果你改变代码如下,他们会在语义上相同的操作..

arr = null; 
0

你cnanot改变参数的任何方法,但你可以做到以下几点。

public static void main(String... args) throws IOException { 
    String[] strings = {"Hello "}; 
    addWorld(strings); 
    System.out.println("Using an array "+Arrays.toString(strings)); 

    StringBuilder text = new StringBuilder("Hello "); 
    addWorld(text); 
    System.out.println("Using a StringBuilder '" + text+"'"); 
} 

private static void addWorld(String[] strings) { 
    for(int i=0;i<strings.length;i++) 
     strings[i] += "World!"; 
    strings = null; // doesn't do anything. 
} 

private static void addWorld(StringBuilder text) { 
    text.append("World !!"); 
    text = null; // doesn't do anything. 
} 

打印

Using an array [Hello World!] 
Using a StringBuilder 'Hello World !!' 
相关问题