Могу ли я передавать параметры по ссылке в Java?

Я бы хотел, чтобы семантика была похожа на ключевое слово C# ref.

Ответ 1

Java запутан, потому что все передано значением. Однако для параметра ссылочного типа (т.е. Не является параметром примитивного типа) это сама ссылка, которая передается по значению, следовательно, она является передачей по ссылке (и люди часто утверждают, что она есть). Это не так, как показано ниже:

Object o = "Hello";
mutate(o)
System.out.println(o);

private void mutate(Object o) { o = "Goodbye"; } //NOT THE SAME o!

Выведет на консоль Hello. Параметры, если вы хотите, чтобы вышеуказанный код печатал Goodbye, должны использовать явную ссылку следующим образом:

AtomicReference<Object> ref = new AtomicReference<Object>("Hello");
mutate(ref);
System.out.println(ref.get()); //Goodbye!

private void mutate(AtomicReference<Object> ref) { ref.set("Goodbye"); }

Ответ 2

Могу ли я передавать параметры по ссылке в Java?

Нет.

Почему? Java имеет только один режим передачи аргументов методам: по значению.

Примечание:

Для примитивов это легко понять: вы получаете копию значения.

Для всех остальных вы получаете копию ссылки, и это называется также передачей по значению.

Все это на картинке:

enter image description here

Ответ 3

В Java нет ничего на уровне языка, подобном ref. В Java существует только передача по смыслу значения

Для любопытства вы можете реализовать ref-like semantic в Java, просто обернув ваши объекты в изменяемый класс:

public class Ref<T> {

    private T value;

    public Ref(T value) {
        this.value = value;
    }

    public T get() {
        return value;
    }

    public void set(T anotherValue) {
        value = anotherValue;
    }

    @Override
    public String toString() {
        return value.toString();
    }

    @Override
    public boolean equals(Object obj) {
        return value.equals(obj);
    }

    @Override
    public int hashCode() {
        return value.hashCode();
    }
}

TestCase:

public void changeRef(Ref<String> ref) {
    ref.set("bbb");
}

// ...
Ref<String> ref = new Ref<String>("aaa");
changeRef(ref);
System.out.println(ref); // prints "bbb"

Ответ 4

От Джеймса Гослинга в "Язык программирования Java":

"... В Java существует ровно один режим передачи параметров - передается по значению - и это упрощает задачу..."

Ответ 5

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

то есть. ваш метод изменяет внутреннее состояние передаваемого объекта, которое затем отображается вызывающему.

Ответ 6

Java всегда проходит по значению.

Когда вы передаете примитив, это копия значения, когда вы передаете объект, это копия ссылочного указателя.

Ответ 7

Другой вариант - использовать массив, например. void method(SomeClass[] v) { v[0] = ...; } но 1) массив должен быть инициализирован до вызова метода, 2) все еще невозможно реализовать, например. метод swap таким образом... Этот способ используется в JDK, например. в java.util.concurrent.atomic.AtomicMarkableReference.get(boolean[]).