11

我在我的代码中发现了一个问题。首先是代码:

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

我假设第一个循环也会覆盖数组中的字符串。所以无论如何输出都会结束。似乎它创建了值的副本而不是创建引用。我从来没有意识到这一点。我做错了吗?是否可以选择创建参考?

//编辑:似乎每个人都知道这一点,除了我。我来自 C 背景,对与 C 非常不同的术语 reference 没有给予足够的关注。幸运的是,我只花了 10 分钟就弄清楚了(这次)。

4

6 回答 6

25

这个:

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));
于 2013-07-31T11:58:23.447 回答
5

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

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

希望从这里你可以看到你所做的只是在s不改变的情况下重新分配一个不同的值blablubb[i]。这解释了您看到的输出。

于 2013-07-31T11:53:00.267 回答
1

for-each 循环不会修改它所迭代的对象集合中包含的对象。它传递的是值而不是引用。

于 2013-07-31T11:52:24.513 回答
0
 s = "over"; 

只是更改 s 的引用而不是数组中的 String 。

blablubb[i] = "over";

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

于 2013-07-31T11:52:49.763 回答
0
for(String s : StringArray)
{
}

就好像

for(int i = 0; i < StringArray.length; i++)
{
    String s = StringArray[i];
}
于 2013-07-31T11:53:07.617 回答
0

当您想要进行低级优化时,知道如何,您必须查看 Java 代码内部和字节码内部(编译代码)

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

等于:

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

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

于 2013-07-31T11:53:39.317 回答