Значение параметра функции Java изменяется - PullRequest
0 голосов
/ 01 февраля 2012

Я написал функцию, которая.Проблема в том, что параметрами, которые я отправляю, манипулируют в основной программе, хотя это не мое намерение.Я просто хочу иметь значение внутри функции, но во время работы фактическое значение в основной программе также изменяется.

Как я могу предотвратить это?

Вот мой код:

    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, на самом деле изменяет сам файл tileArray.Хотя я создал новый экземпляр массива плиток и затем отправил его.

1 Ответ

1 голос
/ 01 февраля 2012

Не видя, что делается в

CopyTilesArrays (tilesArray, tempTilesArrayToSend);

мы не можем сказать много.

Обратите внимание, что в Java нет передачи по значению или передачи по ссылке, но копия ссылки передается методам. Эта копия ссылки - в случае объектов и массивов - будет указывать на один и тот же исходный объект, поэтому, если вы измените базовый / внедренный объект, это повлияет на исходный объект, но если вы измените ссылку, исходный объект не будет пострадавшие.

Если вы хотите передать независимую копию вашего массива, вы должны выполнить глубокий ocpy. Может быть, именно это и должен делать CopyTilesArrays, но, не видя этого, мы не знаем.

Обратите внимание, что есть, или лучше: что может быть несколько слоев объектов с различными причинами оставаться на поверхности, идти к ядру или оставаться где-то посередине.

Например, чтобы сделать глубокую копию из массива плиток, вы можете сделать что-то вроде этого:

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;, но и на глубокую копию, чтобы сохранить объекты в исходном массиве неизменными.

Вы можете скопировать массив массивов плиток несколькими другими способами. Например, вы можете переставить внешний массив. Если бы плитки были

[[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]]
...