Поддерживает ли Java передачу по ссылке?
Если это не так, почему у нас есть оператор == для поиска двух объектов с одинаковой ссылкой?
Поддерживает ли Java передачу по ссылке?
Если это не так, почему у нас есть оператор == для поиска двух объектов с одинаковой ссылкой?
Java использует pass по значению, а не по ссылке...
Но для не примитивных типов значение является значением ссылки.
So == сравнивает значения ссылок для объектов.
Подробное объяснение см. в моей статье "Java Pass-By-Value, Dammit!"
Точка различия между "pass ** - by- reference" и "pass с ссылкой **). Иногда вы также видите, что" call-by -... "и" pass-by -... "используются взаимозаменяемо. Для простоты я буду придерживаться" pass-by -...".
В академической, старой школе, связанной с FORTRAN, терминология comp-sci, pass-by-reference означает, что вызываемый код имеет доступ (ссылку) к переменной, переданной вызывающей. Присвоение формальному параметру в вызываемом коде фактически присваивает переменной вызывающего. Различие по сравнению с (среди прочего) передается по значению, которое дает вызываемому коду копию данных (независимо от того, что это) известна вызывающей стороне.
В современном мире, ориентированном на Java, "наличие ссылки" на объект означает возможность доступа к самому объекту. Это отличается от "указателя", чтобы подчеркнуть (помимо всего прочего), что он не выполняет "арифметику указателя" по ссылке. (Фактически, "ссылка" в этом смысле необязательно должна быть фактическим адресом, подобным указателю.)
Java передает аргументы по значению (в первом смысле), но для аргументов объекта значение является ссылкой (во втором смысле). Здесь немного кода, который зависит от разницы.
// called
public void munge(List<String> a0, List<String> a1) {
List<String> foo = new List<String>(); foo.add("everybody");
a0.set(0, "Goodbye");
a1 = foo;
}
// caller
...
List<String> l0 = new List<String>(); l0.add("Hello");
List<String> l1 = new List<String>(); l1.add("world");
munge(l0, l1);
...
По возвращении из munge
, первый список вызывавших, l0
будет содержать "Goodbye"
. Ссылка на этот список была передана в munge
, которая называется мутирующим методом для этого связанного объекта. (Другими словами, a0
получил копию значения l0
, которая была ссылкой на список строк, который был изменен.)
Однако после возврата из munge
второй список вызывающих абонентов l1
по-прежнему содержит "world"
, потому что не было вызвано никаких методов для ссылки на переданный объект (значение l1
, переданное значением munge
). Вместо этого переменная аргумента a1
получила новое значение (ссылка на локальный объект также хранилась в foo
).
IF Java использовала pass-by-reference, а затем при возврате l1
содержала бы "everybody"
, потому что a1
ссылалась бы на переменную l1
и не просто инициализируется копией его значения. Таким образом, назначение a1
также было бы назначением l1
.
Эта же проблема обсуждалась в другом вопросе, с ASCII-искусством, чтобы проиллюстрировать ситуацию.
Java не использует pass-by-reference, а скорее pass-by-value. Параметры примитивного значения скопированы в стек, а также указатели на объекты.
Оператор ==
должен использоваться для сравнения примитивных значений и для сравнения ссылок на объекты.
Короткий ответ - нет. В Java есть только пропускная способность, а когда вы работаете с объектами (например, Object obj = new Object();
), вы работаете с объектными ссылками. Которые передаются по значению.
Подробнее см. Передача параметров в Java