为什么 Java 参考没有像本程序中预期的那样工作

发布于 2024-08-22 06:05:56 字数 1452 浏览 4 评论 0原文

我正在解决一个问题,我发现 Java 引用没有按照我的预期工作。当然,我是罪魁祸首:),有人可以告诉我为什么会发生以下情况吗?让我先在这里发布代码。

package misc.matrix;

public class ReferenceTester {
    public static void main(String args[]){
        Boolean[][] input = { 
            {true  ,false ,true ,true ,false },
            {false ,true  ,true ,true ,true },
            {true  ,true  ,true ,true ,true },
            {true  ,true  ,true ,true ,true },
            {true  ,false ,true ,true ,true }
        };

        print(input);

        for(Boolean[] eachRow:input){
            for(Boolean eachVal:eachRow){
                eachVal = Boolean.TRUE;
            }
        }
        print(input);

        /*Expected output  
            true  true  true  true  true  
            true  true  true  true  true  
            true  true  true  true  true  
            true  true  true  true  true  
            true  true  true  true  true
        */
    }

    /**
     * Simply prints the array
     */
    private static void print(Boolean[][] input) {
        for(Boolean[] outArray:input){
            for(Boolean iVal:outArray){
                System.out.print(iVal?iVal+"  ":iVal+" ");
            }
            System.out.println();
        }
    }
}

如果您看一下上面的程序,我要做的就是将数组中的所有值更改为 true 并打印它。但它只是再次打印输入。 有人可以告诉我这是为什么吗?最初,我在程序中使用了原始布尔值,但由于我不想创建副本,所以我使用了包装器布尔类,它是一个 Java 对象,而不是原始值。 (eachVal 不是 JAVA OBJECT 吗!?!?!?!?) 为什么在Java中会出现这种情况。为什么它不打印所有的值都是真的?

请指教。

I was working in a problem and I found that Java references are not working as I expect it to. Ofcourse, I am the culprit :), can someone please me why the following happens. Let me first post the code here.

package misc.matrix;

public class ReferenceTester {
    public static void main(String args[]){
        Boolean[][] input = { 
            {true  ,false ,true ,true ,false },
            {false ,true  ,true ,true ,true },
            {true  ,true  ,true ,true ,true },
            {true  ,true  ,true ,true ,true },
            {true  ,false ,true ,true ,true }
        };

        print(input);

        for(Boolean[] eachRow:input){
            for(Boolean eachVal:eachRow){
                eachVal = Boolean.TRUE;
            }
        }
        print(input);

        /*Expected output  
            true  true  true  true  true  
            true  true  true  true  true  
            true  true  true  true  true  
            true  true  true  true  true  
            true  true  true  true  true
        */
    }

    /**
     * Simply prints the array
     */
    private static void print(Boolean[][] input) {
        for(Boolean[] outArray:input){
            for(Boolean iVal:outArray){
                System.out.print(iVal?iVal+"  ":iVal+" ");
            }
            System.out.println();
        }
    }
}

If you take a look at the above program, all I am trying to do is to change all the values in the Array to true and print it. But its simply prints the input again.
Can someone please tell me why is this. Initially I had used the primitive boolean in the program, but since I dont want to create copies, I used the wrapper Boolean Class which is a Java OBJECT as opposed to primitives. (Isnt eachVal a JAVA OBJECT!?!?!?!?)
Why is this happening in Java. Why did it not print all the values to be true?

Please advise.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

留一抹残留的笑 2024-08-29 06:05:56

您无法在 foreach 循环中修改源对象。您的循环必须是标准的 for 循环,如下所示:

for(int i = 0; i < input.length; i++){ 
    for(int j = 0; j < input[i].length; j++){ 
        input[i][j] = true; 
    } 
}

编辑: 更准确地说,循环中的 eachVal 是一个指针,而不是参考;因此将其设置为指向不同的值不会改变原始值。

foreach 循环在幕后使用的确切形式为 这里,如果您想独立确认这一点。

You cannot modify the source object within a foreach loop. Your loop will have to be a standard for loop like this:

for(int i = 0; i < input.length; i++){ 
    for(int j = 0; j < input[i].length; j++){ 
        input[i][j] = true; 
    } 
}

Edit: To be more precise, eachVal in your loop is a pointer, not a reference; hence setting it to point to a different value does not change the original.

The exact form that the foreach loop uses behind the scenes is given here, if you wish to confirm this independently.

有木有妳兜一样 2024-08-29 06:05:56

您的问题是通过循环更改数组的值:

    for(Boolean[] eachRow:input){
        for(Boolean eachVal:eachRow){
            eachVal = Boolean.TRUE;
        }
    }

在每次迭代中,变量 eachVal 保存对数组单元格内容的引用,正如您所期望的那样。但问题是,由于 Boolean 是不可变类型——也就是说,你不能在创建 Boolean 对象后更改它的值——你的作业不起作用。事实上,您实际上所做的是更改 eachVal 引用指向的对象。也就是说,由于 eachVal 是来自 inputeachRow 的独立变量,因此您只需重新分配此变量,而无需触及数组的内容。

如果您希望我详细阐述或澄清任何特定观点,请告诉我。

Your problem is with the loop to change the value of the array:

    for(Boolean[] eachRow:input){
        for(Boolean eachVal:eachRow){
            eachVal = Boolean.TRUE;
        }
    }

On each iteration, the variable eachVal holds a reference to the content of the cell of the array, just as you expect. But the problem is that, since Boolean is an immutable type---that is, you can't change the value of a Boolean object after it's been created---your assignment doesn't work. In fact, what you're actually doing is changing the object that the eachVal reference points to. That is, since eachVal is an independent variable from input and eachRow, you're simply reassigning this variable without ever touching the contents of the array.

Let me know if you want me to expand upon or clarify any particular point.

夜空下最亮的亮点 2024-08-29 06:05:56

@mmyers 有答案,您要求提供更多详细信息,但我无法将其放入评论中:

因此,您有一系列对布尔值的引用(始终是引用),并且在 for every 循环中,您创建了一个指向与该数组的成员相同的布尔值。

每次迭代都会更新引用以指向数组中下一个指针所指向的内容。

当您使用 equals 时,您只需重新分配引用以指向其他内容。

如果你想更新数组中的对象,它必须是可变的(布尔值不是),并且你必须使用变异器而不是等于。

@mmyers had the answer, you asked for more detail but I couldn't fit it in a comment:

So you have an array of references to booleans (it's ALWAYS references) and in your for each loop you create a reference that points to the same boolean as a member of that array.

Each iteration the reference is updated to point to what the next pointer in the array points to.

When you use equals, you are simply re-assigning the reference to point to something else.

If you wanted to update the object inside your array, it would have to be mutable (Boolean is not) and you would have to use a mutator instead of equals.

青柠芒果 2024-08-29 06:05:56

您正在尝试的内容类似于以下内容:

    int[] arr = { 1, 2, 3 };
    for (int i : arr) {
        i = 0;
    }

这不会将数组中的所有值设置为 0。Java 按值传递所有内容。

What you are attempting is analogous to the following:

    int[] arr = { 1, 2, 3 };
    for (int i : arr) {
        i = 0;
    }

This does NOT set all values in the array to 0. Java passes everything by value.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文