Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java: Общие вопросы > Объясните поведение


Автор: lamber 12.10.2011, 17:05
Объясните не понятное поведение с Java работаю не долго и возможно это баян, но все же. В Java все аргументы передаются по ссылке тогда внимание почему такое поведение, код ниже.

Код


public class Main {

    /**
     * @param args
     */
    public static void main(String[] args) {        

        Main obj = new Main();
        obj.TestArr = new int [2][2];
        obj.FillArr(obj.TestArr);
        obj.SomeTestFunction(obj.TestArr);
        obj.PrintArr(obj.TestArr);

    }
    public void SomeTestFunction(int[][] DimArr)
    {
        DimArr = new int[5][5];
        //DimArr = null; при выходе из функции DimArr не будет null
        //DimArr[1][1]=-121; при выходе из функции изменит свое значеним
        //this.PrintArr(DimArr); при инициализации внутри функции выведет массив 5х5
    }
    public void FillArr(int[][] DimArr)
    {
        for(int i=0;i<DimArr.length;i++)
            for(int j=0;j<DimArr[i].length;j++)
            {
                DimArr[i][j]=i+j;
            }
    }
    public void PrintArr(int[][] DimArr)
    {
        for(int i=0;i<DimArr.length;i++)
            for(int j=0;j<DimArr[i].length;j++)
            {
                System.out.print(DimArr[i][j]+" ");
            }
        System.out.print("\n");
    }
    public int[][] TestArr;

}





Автор: Stolzen 12.10.2011, 17:27
Цитата(lamber @  12.10.2011,  18:05 Найти цитируемый пост)
В Java все аргументы передаются по ссылке

Вот и нет. По значению они передаются. В других языках, например, в C# для этого есть аргументы ref и out - но в джаве их нет.

Автор: Nofate 12.10.2011, 17:31
@lamber: Просто объекты являются ссылками, а ссылки переданные по значению остаются ссылками на то же место. Вот и кажется, что передача идет по ссылке. 

То есть в ваших методах вы работаете скопией ссылки на объект. Когда вы делаете DimArr = null, вы просто обнуляете вашу ссылку DimArr, сам объект это разумеется никак не затрагивает. То же самое относится и к другим присвоениям параметра внутри метода.

Автор: lamber 12.10.2011, 23:14
2Nofate и 2Stolzen
Как же тогда выходит что изменяя значения внутри массива эти изменения сохраняются т.е. в том случае когда я пытаюсь изменить значение элементов массива все окей, но стоит мне попробовать изменить размерность массива как выходит что тут же я работаю с копией. 

Автор: Samotnik 12.10.2011, 23:44
Цитата(lamber @  12.10.2011,  23:14 Найти цитируемый пост)
Как же тогда выходит что изменяя значения внутри массива эти изменения сохраняются т.е. в том случае когда я пытаюсь изменить значение элементов массива все окей, но стоит мне попробовать изменить размерность массива как выходит что тут же я работаю с копией.  

Очень просто. Когда ты передаёшь объектную ссылку методу сама ссылка передаётся по значению. Но, т.к. передаваемое значение ссылается на объект, копия этого значения будет ссылаться на тот же объект, что и аргумент.

Автор: Nofate 13.10.2011, 09:00
Рассмотрим пошагово

Случай 1.

Код

obj.PrintArr(obj.TestArr);   //передаем  в качестве параметра ссылку на массив TestArr
    
public void SomeTestFunction(int[][] DimArr)   //в качестве параметра функция получает копию ссылки на массив
{
  DimArr[1][1]=-121;      //поскольку DimArr указывает на тот же массив, что и TestArr, мы меняем значение в исходном массиве  
}                                    // по выходу из функции все изменения остаются в силе, т.к. мы работали с исходным массивом




Случай 2.

Код

obj.PrintArr(obj.TestArr);   //передаем  в качестве параметра ссылку на массив TestArr

public void SomeTestFunction(int[][] DimArr)  //в качестве параметра функция получает копию ссылки на массив
{
  DimArr = new int[5][5];  // мы не меняем размерность массива (опасное заблужение). 
                                        //мы выделяем память под новый массив 5х5 и сохраняем ссылку на него в переменной DimArr
                                        //DimArr больше никак не связана с исходным массивом. она просто указывает на другой объект
}                                      // по выходу из функции все изменения остаются в силе, т.к. мы вообще не трогали исходный массив.


Надеюсь, стало понятнее.

Автор: lamber 13.10.2011, 11:01
Господа спасибо за детальный разбор можно закрывать.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)