Java循环语句按值传递还是按引用传递?

14

我解决了我的代码中的一个问题。首先是代码:

public class Main {

    /**
     * @param args
     */
    public static void main(String[] args) {
        String[] blablubb = { "a", "b", "c" };

        for(String s : blablubb) {
            s = "over";
        }
        printArray(blablubb);


        for (int i = 0; i < blablubb.length; i++) {
            blablubb[i] = "over";
        }
        printArray(blablubb);

    }

    public static void printArray(String[] arr) {
        for( String s : arr ) {
            System.out.println(s);
        }
    }

}

输出结果为:

a
b
c
over
over
over

我原本以为第一个循环也会覆盖数组中的String。所以无论如何,输出结果都将结束。但实际上它创建了值的副本而不是引用。

我以前从未意识到这一点。我做错了吗?有没有选项可以创建引用?

//编辑: 似乎每个人都知道这一点,除了我。我来自C语言背景,并没有足够地关注与C非常不同的术语“引用”。 幸运的是,这次我只花了10分钟就搞清楚了。


3
https://dev59.com/EXVD5IYBdhLWcg3wQJOT - assylias
6个回答

29

这个:

for (String s : blablubb) {
     s = "over";
}

等同于以下内容:

for (int i = 0; i < blablubb.length; i++) {
     String s = blablubb[i];
     s = "over";
}

这将创建一个临时的字符串,其中包含从数组中复制的值,你只会更改副本。这就是为什么blablubb[]的内容保持不变的原因。

如果您想更改数组中的值,请使用第二个选项:

for (int i = 0; i < blablubb.length; i++) {         
    blablubb[i] = "over";
}

顺便说一下,您可以只用一行代码打印一个数组:

System.out.println(Arrays.toString(blablubb));

5

您的for(String s : blablubb)循环等同于以下代码:

for(int i = 0; i < blablubb.length; i++ ) {
    String s = blablubb[i];
    s = "over";
}

希望您能看出,您所做的只是将不同的值重新分配给“s”,而没有改变“blablubb[i]”。这就解释了您看到的输出结果。

2
< p > for-each循环不会修改正在迭代的对象集合中包含的对象。它传递的是值而不是引用。 < /p >

0
 s = "over"; 

只是改变了 s 的引用,而不是数组中的字符串。

blablubb[i] = "over";

更改数组中第i个位置存储的值


0
for(String s : StringArray)
{
}

就像

for(int i = 0; i < StringArray.length; i++)
{
    String s = StringArray[i];
}

-1

当你想进行低级别的优化时,你必须深入了解Java代码和字节码(编译后的代码)。

for(String s : blablubb) {
            s = "over";
}

相等于:

for (int i = 0; i < blablubb.length; i++) {
     String s = blablubb[i];            
     s = "over";
}

这就是为什么输出是这样的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接