159

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

oxbow_lakes
  • 133,303
  • 56
  • 317
  • 449
ripper234
  • 222,824
  • 274
  • 634
  • 905

8 Answers8

248

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"); }
oxbow_lakes
  • 133,303
  • 56
  • 317
  • 449
  • 52
    Also, an array of length 1 can be used to create a reference if you really want to confuse people :) – Christoffer Jul 01 '09 at 12:18
  • 2
    AtomicReference and corresponding classes (AtomicInteger) are best for such operations – Naveen Jul 13 '11 at 19:50
  • 5
    AtomicReference is an overkill, you don't necessarily want memory barrier there, and they might cost you. JRuby had perfomance problem because of a volatile variable used when constructing an Object. The option of using array as an ad-hoc reference seems good enough for me, and I've seen it used more than once. – Elazar Leibovich Oct 30 '12 at 14:34
  • I do not think that this is confusing, however this is normal behavior.Value types exist on stack and reference types exist on heap, but reference to for reference types exist on stack also. Thus you always operate with value that is on the stack. I believe that the question here was: Is it possible to pass reference from stack that points on some other value that is also on stack. Or pass reference of other reference which points on some value that lives on heap? – eomeroff Nov 21 '12 at 09:38
  • this i great info. i had been using arrays but this seems like something built for the job. i don't know about performance of this vs. arrays however, if in a performance critical loop – steveh Apr 07 '13 at 05:43
  • @oxbow_lakes, Does the Java library have a non-atomic version of AtomicReference? – Pacerier Jul 25 '14 at 12:03
68

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

PeterMmm
  • 24,152
  • 13
  • 73
  • 111
28

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"
dfa
  • 114,442
  • 31
  • 189
  • 228
  • 1
    Why not use java.lang.ref.Reference instead? – Hardcoded Nov 27 '09 at 13:31
  • 1
    java.lang.ref.Reference don't have a set method, it is not mutable – dfa Nov 27 '09 at 14:00
  • why not use `AtomicReference` (for non-primitives)? Or `AtomicSomething` (e.g.: `AtomicBoolean`) for primitives? – Arvin Nov 05 '13 at 02:39
  • Unfortunately, does not accept primitive types. Would like to do this: Ref – jk7 Apr 21 '17 at 16:05
  • 1
    @jk7 Is it really important enough to have to use `int` instead of `Integer`, `bool` instead of `Boolean` and so on? That is, wrapper classes (which are automatically unwrapped if you worry about syntax) don't work? – Paul Stelian Dec 30 '18 at 18:05
  • @Paul Stelian : Good point. Having a wrapper of a wrapper seems like an inefficient implementation, but it is unlikely to make a noticeable difference in most cases. – jk7 Jan 01 '19 at 20:25
  • @jk7 I seriously doubt you'd worry about performance of that in Java in any case – Paul Stelian Jan 02 '19 at 09:06
22

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

duffymo
  • 305,152
  • 44
  • 369
  • 561
  • 3
    The pronouncement of the language god should be declared the answer. – ingyhere Oct 25 '13 at 21:25
  • 4
    @ingyhere : `The pronouncement of the language god should be declared the answer` : Not really. Despite what the creator of Java thinks or believe, the absolute answer would come from a quote from the language specification. – paercebal Feb 05 '15 at 10:03
  • 2
    In fact it is in the [JLS, in section 8.4.1](http://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.4.1), and the JLS cites Gosling as first author: "When the method or constructor is invoked (§15.12), **the values of the actual argument expressions initialize newly created parameter variables**, each of the declared type, before execution of the body of the method or constructor." – ingyhere Feb 09 '15 at 20:53
11

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.

Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
9

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.

Nick Holt
  • 33,455
  • 4
  • 52
  • 58
5

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[]).

Michal Misiak
  • 164
  • 2
  • 4
0

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