Ничего не передается по ссылке в Java - но вам нужно знать, каково значение переменной.
Значением переменной типа int[]
является , а не массив. Это ссылка на массив. Все массивы являются ссылочными типами, даже если это массив примитивов.
Когда вы пишете:
int[] x = { 1, 2, 3, 4, 5 };
someMethod(x);
затем значение из x передается по значению в someMethod
. Это ссылка на массив - метод может изменить содержимое массива, но он не сможет изменить значение самого x
, что он мог бы сделать, если бы в Java использовалась передача по ссылке.
Как только вы поймете, что значение любого выражения является либо ссылочным, либо примитивным значением, многие вещи становятся понятнее. Например, возьмите этот код:
int[] x = { 1, 2, 3, 4, 5 };
int[] y = x;
y[0] = 10;
System.out.println(x[0]);
Каким вы ожидаете получить результат? Оператор присваивания копирует значение из RHS в LHS, поэтому x
и y
являются ссылками на один и тот же массив. Поэтому в последней строке выводится 10. Это «копирование значения» в точности соответствует принципу, используемому для передачи аргументов.
Здесь нет противоречий - вам просто нужно понять, что происходит, и что на самом деле означают передача по значению и передача по ссылке.
РЕДАКТИРОВАТЬ: Я действительно удивлен, есть еще сомнения по этому поводу.
Из спецификации языка Java, раздел 8.4.1 (формальные параметры) :
Когда вызывается метод или конструктор (§15.12), значения фактических выражений аргумента инициализируют вновь созданные переменные параметра, каждый из объявленного типа, перед выполнением тела метода или конструктора
Это практически определение семантики передачи по значению: значения аргументов используются в качестве начальных значений параметров.
Эти значения могут быть ссылками или примитивными значениями - это не меняет того факта, что передается значение .
РЕДАКТИРОВАТЬ: определение, которое вы используете, хотя и плохо выражено, на мой взгляд, безусловно, не означает, что утверждение, что Java передает все по значению, вводит в заблуждение.
Это говорит, для передачи по значению:
Это делает копию переменной и
может быть довольно медленным и неэффективным, если
переменная большая, как массив.
Обратите внимание, что речь шла о C и C ++ (хотя в C ++ действительно также есть передача по ссылке). В нем говорится о создании копии переменной . Это именно то, что делает Java. Разница в том, что в Java значение переменной всегда либо примитивное значение, либо ссылка. Это никогда не объект.
Как только вы поймете, что критическая точка (и это важно не только для передачи аргументов), очень просто правильно сказать, что Java передает все по значению. Когда вызывается метод или конструктор, аргументы оцениваются, и значения используются в качестве начальных значений параметров. Это передача по значению, и именно это делает Java для всех параметров.
Что касается PDF, на который вы ссылаетесь - это позорно плохое обсуждение темы, ИМО. Это путает то, что передается по ссылке, это особые случаи String без веской причины (String бывает неизменным, но могут быть и другие классы), и это в целом неправильно. Поможет ли мне дать несколько ссылок, поддерживающих мою точку зрения?
Есть еще сотни. Вы не первый, кого это смущает, но Java действительно передает все по значению, даже ссылки.