Java сбивает с толку, потому что все передается по значению . Однако для параметра ссылочного типа (т. Е. Не для параметра примитивного типа) это сама ссылка, которая передается по значению, следовательно, она кажется передачей по ссылке (и люди часто утверждают, что это так). Это не тот случай, о чем свидетельствует следующее:
Object o ="Hello";
mutate(o)System.out.println(o);privatevoid mutate(Object o){ o ="Goodbye";}//NOT THE SAME o!
Распечатает Helloна консоль. Опции, если вы хотите, чтобы вышеприведенный код печатался Goodbye, должны использовать явную ссылку следующим образом:
Кроме того, массив длины 1 может использоваться для создания ссылки, если вы действительно хотите запутать людей :)
Christoffer
2
AtomicReference и соответствующие классы (AtomicInteger) являются лучшими для таких операций
Naveen
3
AtomicReference - это излишество, вам не обязательно иметь барьер памяти, и они могут стоить вам. У JRuby была проблема производительности из-за изменчивой переменной, используемой при создании объекта. Вариант использования массива в качестве специальной ссылки мне кажется достаточно хорошим, и я видел, что он использовался не раз.
Элазар Лейбович
Я не думаю, что это сбивает с толку, однако это нормальное поведение. Типы значений существуют в стеке, а ссылочные типы существуют в куче, но ссылки на ссылочные типы также существуют в стеке. Таким образом, вы всегда работаете со значением, которое находится в стеке. Я полагаю, что вопрос здесь был: возможно ли передать ссылку из стека, которая указывает на какое-то другое значение, которое также находится в стеке. Или передать ссылку на другую ссылку, которая указывает на какое-то значение, которое живет в куче?
eomeroff
это я отличная информация. я использовал массивы, но это похоже на что-то созданное для работы. однако я не знаю, как это работает по сравнению с массивами, если в цикле, критичном к производительности,
steveh
65
Могу ли я передать параметры по ссылке в Java?
Нет.
Зачем ? В Java есть только один способ передачи аргументов в методы: по значению.
Примечание:
Для примитивов это легко понять: вы получаете копию значения.
Для всех остальных вы получаете копию ссылки, и это также называется передачей по значению.
Почему бы не использовать вместо этого java.lang.ref.Reference?
Закодировано
У java.lang.ref.Reference нет метода set, он не изменяем
dfa
почему бы не использовать AtomicReference(для не примитивов)? Или AtomicSomething(например:) AtomicBooleanдля примитивов?
Арвин
К сожалению, <T> не принимает примитивные типы. Хотелось бы сделать это: Ref <int>
jk7
1
@ jk7 Достаточно ли важно использовать intвместо Integer, boolвместо Booleanи так далее? То есть классы-обертки (которые автоматически разворачиваются, если вы беспокоитесь о синтаксисе) не работают?
Пол Стелиан
18
От Джеймса Гослинга из "Языка программирования Java":
«... В Java существует ровно один режим передачи параметров - передача по значению - и это упрощает задачу…»
Объявление бога языка должно быть объявлено ответом.
ingehere
3
@ingyhere :: The pronouncement of the language god should be declared the answerНе совсем. Несмотря на то, что создатель Java думает или верит, абсолютный ответ будет взят из цитаты из спецификации языка.
paercebal
1
Фактически это в JLS, в разделе 8.4.1 , и JLS цитирует Гослинга как первого автора: «Когда вызывается метод или конструктор (§15.12), значения фактических выражений аргумента инициализируют вновь созданные переменные параметра , каждый объявленного типа, перед выполнением тела метода или конструктора. "
ingehere
Именно. Сарказм от членов с низким числом представителей не помогает.
Duffymo
11
Я не думаю, что ты можешь. Наилучшим вариантом может быть инкапсуляция того, что вы хотите передать «по ссылке», в другой экземпляр класса и передать ссылку на (внешний) класс (по значению). Если вы понимаете, что я имею в виду ...
т. е. ваш метод изменяет внутреннее состояние передаваемого объекта, который затем становится видимым для вызывающей стороны.
Другим вариантом является использование массива, например,
void method(SomeClass[] v) { v[0] = ...; }
но 1) массив должен быть инициализирован перед вызовом метода, 2) тем не менее, никто не может реализовать, например, метод swap таким образом ... Этот способ используется в JDK, например, в java.util.concurrent.atomic.AtomicMarkableReference.get(boolean[]).
Ответы:
Java сбивает с толку, потому что все передается по значению . Однако для параметра ссылочного типа (т. Е. Не для параметра примитивного типа) это сама ссылка, которая передается по значению, следовательно, она кажется передачей по ссылке (и люди часто утверждают, что это так). Это не тот случай, о чем свидетельствует следующее:
Распечатает
Hello
на консоль. Опции, если вы хотите, чтобы вышеприведенный код печаталсяGoodbye
, должны использовать явную ссылку следующим образом:источник
Нет.
Зачем ? В Java есть только один способ передачи аргументов в методы: по значению.
Примечание:
Для примитивов это легко понять: вы получаете копию значения.
Для всех остальных вы получаете копию ссылки, и это также называется передачей по значению.
Это все на этой картинке:
источник
В Java на уровне языка нет ничего похожего на ref . В Java есть только передача по значению семантической
Ради любопытства вы можете реализовать в Java рефлексивную семантику, просто оборачивая ваши объекты в изменяемый класс:
прецедент:
источник
AtomicReference
(для не примитивов)? ИлиAtomicSomething
(например:)AtomicBoolean
для примитивов?int
вместоInteger
,bool
вместоBoolean
и так далее? То есть классы-обертки (которые автоматически разворачиваются, если вы беспокоитесь о синтаксисе) не работают?От Джеймса Гослинга из "Языка программирования Java":
источник
The pronouncement of the language god should be declared the answer
Не совсем. Несмотря на то, что создатель Java думает или верит, абсолютный ответ будет взят из цитаты из спецификации языка.Я не думаю, что ты можешь. Наилучшим вариантом может быть инкапсуляция того, что вы хотите передать «по ссылке», в другой экземпляр класса и передать ссылку на (внешний) класс (по значению). Если вы понимаете, что я имею в виду ...
т. е. ваш метод изменяет внутреннее состояние передаваемого объекта, который затем становится видимым для вызывающей стороны.
источник
Java всегда передается по значению.
Когда вы передаете примитив, это копия значения, когда вы передаете объект, это копия указателя ссылки.
источник
Другим вариантом является использование массива, например,
void method(SomeClass[] v) { v[0] = ...; }
но 1) массив должен быть инициализирован перед вызовом метода, 2) тем не менее, никто не может реализовать, например, метод swap таким образом ... Этот способ используется в JDK, например, вjava.util.concurrent.atomic.AtomicMarkableReference.get(boolean[])
.источник