Может кто-нибудь объяснить, как Java передается по значению только тогда, когда - PullRequest
3 голосов
/ 29 августа 2011

Когда я беру массив, что-то вроде этого:

int anArray[] = new int[5];
//initialize to 0

doStuff(anArray);

//inside doStuff
anArray[3] = 731;
//passes back to main

System.out.println(anArray[3]); // outputs 731

Разве это не передача по ссылке? Что дает?

Ответы [ 4 ]

5 голосов
/ 29 августа 2011

Типы ссылок, такие как массивы, по-прежнему считаются передачей по значению, поскольку вы передаете копию значения ссылки. Обратите внимание, что вы не передаете реальный дескриптор ссылки. То есть ваш метод doStuff не может изменить ссылку на anArray, как это было бы возможно при передаче семантики ссылок. Пример должен помочь понять разницу:

int anArray[] = new int[] { 99, 100};

doStuff(anArray);
...

//inside doStuff 
anArray = new int[] { 68, 69};

...
// back in anArray's original scope
System.out.println(anArray[1]); // still outputs 100, not 69
2 голосов
/ 29 августа 2011

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

Вы можете рассматривать ссылку как просто ссылку или указатель на ваш массив.Ссылка, как правило, представляет собой небольшое значение, указывающее вашей программе, как добраться до интересующего вас объекта по адресу его памяти.Скажем, ссылка указывает на адрес памяти 100. Когда вы передаете ссылку методу, она передается по значению, поэтому метод получает копию ссылки.В метод вводится новое значение 100.

Когда вы пытаетесь что-то сделать с массивом в этом методе, значение ссылки рассматривается и используется для получения доступа к объекту в памяти.Итак, мы ищем адрес 100, получаем объект, который нам нужен, и заканчиваем.

После выхода из метода значение ссылки внутри метода исчезает (это была локальная переменная), но вне метода у вас все еще есть копия ссылки, и вы все равно можете использовать ее для доступаадрес 100, где ваш объект.

1008 * Итак, мы просто получить представление о том, что объект передается по ссылке, когда вместо того, чтобы объект всегда находится в том же месте в памяти, и мы просто проездом эталонное значение, которое получаетскопировано.Поскольку копия имеет тот же адрес значения, что и вне метода, мы можем получить доступ к тому же объекту.
1 голос
/ 29 августа 2011

Вы изменяете состояние изменяемого объекта, в данном случае массива.Однако, попробовав этот код, вы обнаружите, что функция doStuff возвращает массив, переданный по значению:

public class try1
{

  static void doStuff(int[] anArray)
  {
    anArray = new int[] {
        5, 6, 7
    };
    System.out.println(java.util.Arrays.toString(anArray));
  }

  public static void main(String[] args)
  {
    int[] anArray = new int[] {
        0, 1, 2
    };
    System.out.println(java.util.Arrays.toString(anArray));

    doStuff(anArray);
    System.out.println(java.util.Arrays.toString(anArray));
  }

}
0 голосов
/ 29 августа 2011

Java передается по значению. Период.

Метод всегда получает копию значения содержимого переменной. Это относится как к примитивам, так и к объектам. В случае объектов значение переменной является адресом, который сообщает JVM, как найти объект в памяти кучи.

В вашем случае переменная anArray в начале и переменная внутри функции doStuff содержат одинаковое значение, которое сообщает JVM, как извлечь тот же самый массив (только один) в памяти. Вот и все.

Обратите внимание, что мне даже не приходилось использовать слово "ссылка", чтобы дать этот ответ ... И нет, я никогда не буду использовать слово "указатель", когда говорю о Java.

Огромная дискуссия о передаче по ссылке против значения здесь .

...