Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I pass a primitive data type by reference?

How can I pass a primitive type by reference in java? For instance, how do I make an int passed to a method modifiable?

like image 765
Neuquino Avatar asked Nov 30 '10 22:11

Neuquino


People also ask

Are primitive types passed by reference?

Objects are passed by reference and primitive types are passed by value. A correct statement would be: Object references are passed by value, as are primitive types. Thus, Java passes by value, not by reference, in all cases.

How do you pass a primitive data type as a reference in Java?

In Java, it is not possible to pass primitives by reference. To emulate this, you must pass a reference to an instance of a mutable wrapper class.

How is primitive data type passed?

Primitive data types are passed, or copied, by value and are immutable, meaning that the existing value cannot be altered the way an array or an object can.

Which data types are passed by reference?

Primitive data types such as string, number, null, undefined, boolean, are passed by value while non-primitive data types such as objects, arrays, and functions are passed by reference in Javascript.


3 Answers

Nothing in java is passed by reference. It's all passed by value.

Edit: Both primitives and object types are passed by value. You can never alter the passed value/reference and expect the originating value/reference to change. Example:

String a;
int b;

doSomething(a, b);

...

public void doSomething(String myA, int myB) {
   // whatever I do to "myA" and "myB" here will never ever ever change
   // the "a" and "b"
}

The only way to get around this hurdle, regardless of it being a primitive or reference, is to pass a container object, or use the return value.

With a holder:

private class MyStringHolder {
  String a;
  MyStringHolder(String a) {
    this.a = a;
  }
}

MyStringHolder holdA = new MyStringHolder("something");

public void doSomething(MyStringHolder holder) {
   // alter holder.a here and it changes.
}

With return value

int b = 42;
b = doSomething(b);

public int doSomething(int b) {
  return b + 1;
}
like image 45
Martin Algesten Avatar answered Oct 23 '22 17:10

Martin Algesten


There isn't a way to pass a primitive directly by reference in Java.

A workaround is to instead pass a reference to an instance of a wrapper class, which then contains the primitive as a member field. Such a wrapper class could be extremely simple to write for yourself:

public class IntRef { public int value; }

But how about some pre-built wrapper classes, so we don't have to write our own? OK:

The Apache commons-lang Mutable* classes:
Advantages: Good performance for single threaded use. Completeness.
Disadvantages: Introduces a third-party library dependency. No built-in concurrency controls.
Representative classes: MutableBoolean, MutableByte, MutableDouble, MutableFloat, MutableInt, MutableLong, MutableObject, MutableShort.

The java.util.concurrent.atomic Atomic* classes:
Advantages: Part of the standard Java (1.5+) API. Built-in concurrency controls.
Disadvantages: Small performance hit when used in a single-threaded setting. Missing direct support for some datatypes, e.g. there is no AtomicShort.
Representative classes: AtomicBoolean, AtomicInteger, AtomicLong, and AtomicReference.
Note: As user ColinD shows in his answer, AtomicReference can be used to approximate some of the missing classes, e.g. AtomicShort.

Length 1 primitive array
OscarRyz's answer demonstrates using a length 1 array to "wrap" a primitive value.
Advantages: Quick to write. Performant. No 3rd party library necessary.
Disadvantages: A little dirty. No built-in concurrency controls. Results in code that does not (clearly) self-document: is the array in the method signature there so I can pass multiple values? Or is it here as scaffolding for pass-by-reference emulation?

Also see
The answers to StackOverflow question "Mutable boolean field in Java".

My Opinion
In Java, you should strive to use the above approaches sparingly or not at all. In C it is common to use a function's return value to relay a status code (SUCCESS/FAILURE), while a function's actual output is relayed via one or more out-parameters. In Java, it is best to use Exceptions instead of return codes. This frees up method return values to be used for carrying the actual method output -- a design pattern which most Java programmers find to be more natural than out-parameters.

like image 59
14 revs Avatar answered Oct 23 '22 19:10

14 revs


Pass an AtomicInteger, AtomicBoolean, etc. instead. There isn't one for every primitive type, but you can use, say, an AtomicReference<Short> if necessary too.

Do note: there should very rarely be a need to do something like this in Java. When you want to do it, I'd recommend rethinking what you're trying to do and seeing if you can't do it some other way (using a method that returns an int, say... what exactly the best thing to do is will vary from situation to situation).

like image 13
ColinD Avatar answered Oct 23 '22 18:10

ColinD