Can I pass parameters by reference in Java?

C#JavaReference

C# Problem Overview


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

C# Solutions


Solution 1 - C#

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"); }

Solution 2 - C#

> 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

Solution 3 - C#

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"

Solution 4 - C#

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. .."

Solution 5 - C#

I don't think you can. Your best option might be to encapsulate the thing you want to pass "by ref" onto another class instance, and pass the (outer) class's reference (by value). If you see what I mean...

i.e. your method changes the internal state of the object it is passed, which is then visible to the caller.

Solution 6 - C#

Java is always pass by value.

When you pass a primitive it's a copy of the value, when you pass an object it's a copy of the reference pointer.

Solution 7 - C#

Another option is to use an array, e.g. void method(SomeClass[] v) { v[0] = ...; } but 1) the array must be initialized before method invoked, 2) still one cannot implement e.g. swap method in this way... This way is used in JDK, e.g. in java.util.concurrent.atomic.AtomicMarkableReference.get(boolean[]).

Solution 8 - C#

Check out my response in: http://stackoverflow.com/a/9324155/1676736

In there I used a simpler version of the wrapper class idea. I don't like setters/getters as a standard. When there is no reason to bury a field I make it 'public'. Especially in something like this.

However, this would work for all but the primitive, or multi-parameter/type returns:

public class Ref<T> {
    public T val;
}

Although, I suppose you could just add more type parameters. But I think that creating an inner static class fit-for-purpose would be easier:

public static class MyReturn {
    public String name;
    public int age;
    public double salary;
}

this would be for use when you don't need it for other reasons.

MyReturn mRtn = new MyReturn();

public void myMethod(final MyReturn mRtn){
    mRtn.name = "Fred Smith";
    mRtn.age = 32;
    mRtn.salary = 100000.00;
}

System.out.println(mRtn.name + " " +mRtn.age + ": $" + mRtn.salary);

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionripper234View Question on Stackoverflow
Solution 1 - C#oxbow_lakesView Answer on Stackoverflow
Solution 2 - C#PeterMmmView Answer on Stackoverflow
Solution 3 - C#dfaView Answer on Stackoverflow
Solution 4 - C#duffymoView Answer on Stackoverflow
Solution 5 - C#Marc GravellView Answer on Stackoverflow
Solution 6 - C#Nick HoltView Answer on Stackoverflow
Solution 7 - C#Michal MisiakView Answer on Stackoverflow
Solution 8 - C#Bradley WillcottView Answer on Stackoverflow