Java函数参数值正在改变

标签 java function parameters pass-by-reference pass-by-value

我写了一个函数。问题是,我发送的参数正在主程序中被操纵,尽管这不是我的意图。我只是想要函数内部的值,但是在操作的时候,主程序中的实际值也在被改变。

如何防止这种情况发生?

这是我的代码:

    Tiles[][] MoveRight(Tiles[][] tilesArray) {


    Tiles[][] tempTilesArray = new Tiles[3][3];
    Tiles[][] tempTilesArrayToSend = new Tiles[3][3];

    tempTilesArrayToSend = CopyTilesArrays(tilesArray, tempTilesArrayToSend);

    ArrayIndex zeroPos = FindZero(tilesArray);

    Tiles zeroTile = GetTile(zeroPos, tilesArray);

    if (zeroPos.column != 2) {
        ArrayIndex otherPos = new ArrayIndex(zeroPos.row,
                zeroPos.column + 1);
        tempTilesArray = SwapTilesPositions(zeroTile, GetTile(otherPos,
                tilesArray), tempTilesArrayToSend);
    }
    return tempTilesArray;

}

我在 SwapPositionFunction 内发送的数组实际上是在修改tilesArray本身。虽然我已经创建了一个tiles数组的新实例然后发送了它。

最佳答案

没有看到做了什么

CopyTilesArrays (tilesArray, tempTilesArrayToSend);

我们不能说太多。

请注意,在 Java 中,没有按值传递或按引用传递,而是将引用的副本传递给方法。引用的此副本将(在对象和数组的情况下)指向相同的原始对象,因此如果更改基础/嵌入对象,原始对象会受到影响,但如果更改引用,原始对象不会受到影响做作的。

如果您想传递数组的独立副本,则必须执行深度复制。也许这就是 CopyTilesArrays 应该做的事情,但如果没有看到它,我们不知道。

还要注意,存在,或者更好的是:可以有多层对象,出于不同的原因停留在表面、进入核心或停留在中间的某个位置。

例如,要从 Array of Array of Tiles 进行深层复制,您可以执行以下操作:

public class TilesCopy {
    Tiles[][] copyTilesArrays (Tiles[][] from, int outer, int inner) {
        Tiles[][] to = new Tiles[outer][inner];
        int o = 0;
        for (Tiles [] tiles: from) {
            Tiles[] fresh = new Tiles [inner];
            int i = 0;
            for (Tiles t : tiles) 
            {
                fresh[i] = t.deepCopy ();
                i++;
            }
            to [o] = fresh; 
            o++;
        }
        return to; 
    }
}

请注意,在最内层循环中,元素不仅通过 fresh[i] = t; 引用,而且通过深层复制来引用,以保持原始数组中的对象不受影响。

您可以通过多种其他方式复制 Tiles 数组的数组。例如,您可以重新排列外部数组。如果瓷砖是

[[A][B][C]]
[[D][E][F]]
[[G][H][I]]

您可以复制它们,并将目标修改为:

[[G][H][I]]
[[D][E][F]]
[[A][B][C]]

只需复制外部数组并重新排列它们即可。你可以复制内部数组,如下:

[[C][B][A]]
[[F][E][D]]
[[I][H][G]]

如果现在将A修改为a,原来的A也会受到影响,没有深拷贝:

[[C][B][a]]
[[F][E][D]]
[[I][H][G]]

[[a][B][C]]
[[D][E][F]]
[[G][H][I]]

关于Java函数参数值正在改变,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9086813/

相关文章:

javascript - 在 JavaScript 中生成所有可能的可变长度逗号分隔字符串组合

html - 怎么有xsl :function return a string value including html tags

c++ - 将函数输出直接传递给接受引用参数的函数?

java - 动态添加 JTextFields 后将其删除

java - 在 JOOQ 中构建动态表连接

java - 来自两个位置的相同 NetBeans 项目

java - JQuery-UI 自动完成下拉菜单未显示所需结果

javascript - 在两个不同的类上运行 Javascript Jquery 函数

c# - ASP.NET MVC URl 路由 : How to deal with ? Action=测试参数

symfony - 获取 AppKernel.php 中的 parameters.yml 参数