How to do the equivalent of pass by reference for primitives in Java
You have several choices. The one that makes the most sense really depends on what you're trying to do.
Choice 1: make toyNumber a public member variable in a class
class MyToy {
public int toyNumber;
}
then pass a reference to a MyToy to your method.
void play(MyToy toy){
System.out.println("Toy number in play " + toy.toyNumber);
toy.toyNumber++;
System.out.println("Toy number in play after increement " + toy.toyNumber);
}
Choice 2: return the value instead of pass by reference
int play(int toyNumber){
System.out.println("Toy number in play " + toyNumber);
toyNumber++;
System.out.println("Toy number in play after increement " + toyNumber);
return toyNumber
}
This choice would require a small change to the callsite in main so that it reads, toyNumber = temp.play(toyNumber);
.
Choice 3: make it a class or static variable
If the two functions are methods on the same class or class instance, you could convert toyNumber into a class member variable.
Choice 4: Create a single element array of type int and pass that
This is considered a hack, but is sometimes employed to return values from inline class invocations.
void play(int [] toyNumber){
System.out.println("Toy number in play " + toyNumber[0]);
toyNumber[0]++;
System.out.println("Toy number in play after increement " + toyNumber[0]);
}
Passing primitive data by 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.
See How do I pass a primitive data type by reference? for more info on mutable wrapper classes.
How do I pass a primitive data type by reference?
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.
Can I pass a primitive type by reference in Java?
While Java supports overloading, all parameters are passed by value, i.e. assigning a method argument is not visible to the caller.
From your code snippet, you are trying to return a value of different types. Since return types are not part of a method's signature, you can not overload with different return types. Therefore, the usual approach is:
int getIntValue() { ... }
byte getByteValue() { ... }
If this is actually a conversion, the standard naming is
int toInt() { ...}
byte toByte() { ... }
JAVA Pass Primitive type as a Reference to function call
Are you aware of java streams? With streams you can do something like:
List<Object> result = objects.stream()
.filter(object -> {/*add condition here*/})
.map(object->{/*do something with object that match condition above*/})
.collect(Collectors.toList());
You can use this mechanism to collect and process objects based on certain conditions.
If that doesn't help, maybe use an iterator?
Iterator<Object> it = objects.iterator();
while(it.hasNext()){
Object node = someFunction(session,it);
}
public Object someFunction(Session session,Iterator i){
//manipulate i value based on condition
if(true){
i.next();
}else{
i.next();
i.next();
}
}
java pass by value primitive vs objects
You pass the reference of the BirthDate
by value, so your method refers to the same BirthDate
as in your main method.
However you then change the member of that object (lear
) from 200 to 400.
Because you've passed the reference to the original object, it's not been copied and you're dealing with the same object at all times.
A reference to primitive type in Java (How to force a primitive data to remain boxed)
Integer
is immutable, as you may notice.
Your approach with private static class IntegerWrapper
is correct one. Using array with size 1 is also correct, but in practice I have never seen using array for this case. So do use IntegerWrapper.
Exactly the same implementation you can find in Apache org.apache.commons.lang3.mutable.MutableInt
.
In your example you also can provide Main
instance to the static method:
public class Main {
private int x = 42;
public static void main(String[] args) {
Main main = new Main();
incrementX(main);
}
private static void incrementX(Main main) {
main.x++;
}
}
And finally, from Java8 you could define an inc
function and use it to increment value:
public class Main {
private static final IntFunction<Integer> INC = val -> val + 1;
private int x = 42;
public static void main(String[] args) {
Main main = new Main();
main.x = INC.apply(main.x);
}
}
Related Topics
Unresponsive Keylistener for Jframe
Strings Are Objects in Java, So Why Don't We Use 'New' to Create Them
Javafx: Location Is Not Set Error
Java Date Format Conversion - Getting Wrong Month
Getting Rsa Private Key from Pem Base64 Encoded Private Key File
Get Source Jars from Maven Repository
List of All Special Characters That Need to Be Escaped in a Regex
Java: Error: Variable Might Not Have Been Initialized
How to Convert Currenttimemillis to a Date in Java
Problems Converting Byte Array to String and Back to Byte Array
Handling Passwords Used for Auth in Source Code
Rotating Coordinate Plane for Data and Text in Java
How to Get Java 11 Run-Time Environment Working Since There Is No More Jre 11 for Download
How to Put Axis on a .Png File in Java