Can I pass parameters by reference in Java?

I'd like semantics similar to C#'s ref keyword.


Java is confusing because everything is passed by value. However for a parameter of reference type (i.e. not a parameter of primitive type) it is the reference itself which is passed by value, hence it appears to be pass-by-reference (and people often claim that it is). This is not the case, as shown by the following:

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

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

Will print Hello to the console. The options if you wanted the above code to print Goodbye are to use an explicit reference as follows:

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

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

Can I pass parameters by reference in Java?

No.

Why ? Java has only one mode of passing arguments to methods: by value.

Note:

For primitives this is easy to understand: you get a copy of the value.

For all other you get a copy of the reference and this is called also passing by value.

It is all in this picture:

enter image description here


In Java there is nothing at language level similar to ref. In Java there is only passing by value semantic

For the sake of curiosity you can implement a ref-like semantic in Java simply wrapping your objects in a mutable class:

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"

From James Gosling in "The Java Programming Language":

"...There is exactly one parameter passing mode in Java - pass by value - and that keeps things simple. .."