Java is pass-by-value. How could you modify the language to introduce passing by reference (or some equivalent behavior)?
Take for example something like
public static void main(String[] args) {
String variable = "'previous String reference'";
passByReference(ref variable);
System.out.println(variable); // I want this to print 'new String reference'
}
public static void passByReference(ref String someString) {
someString = "'new String reference'";
}
which (without the ref
) compiles to the following bytecode
public static void main(java.lang.String[]);
Code:
0: ldc #2 // String 'previous String reference'
2: astore_1
3: aload_1
4: invokestatic #3 // Method passByReference:(Ljava/lang/String;)V
7: return
public static void passByReference(java.lang.String);
Code:
0: ldc #4 // String 'new String reference'
2: astore_0
3: return
The code at 3:
loads the reference onto the stack from the variable variable
.
One possibility I'm considering is to have the compiler determine a method is pass by reference, possibly with ref
, and change the method to accept a Holder object which stores the same reference as our variable. When the method completes, and possibly changes that reference in the holder, the variable on the caller side's value is replaced with the holder reference's value.
It should compile to an equivalent of this
public static void main(String[] args) {
String variable = "'previous String reference'";
Holder holder = Holder.referenceOf(variable);
passByReference2(holder);
variable = (String) holder.getReference(); // I don't think this cast is necessary in bytecode
System.out.println(variable);
}
public static void passByReference(Holder someString) {
someString.setReference("'new String reference'");
}
where Holder
might be something like
public class Holder {
Object reference;
private Holder (Object reference) {
this.reference = reference;
}
public Object getReference() {
return this.reference;
}
public void setReference(Object reference) {
this.reference = reference;
}
public static Holder referenceOf(Object reference) {
return new Holder(reference);
}
}
Where can this fail or how could you improve it?
OUT
andINOUT
operation parameters. As parameters might get updated with new values, these changes need to be returned appropriately to the caller. Java provides therefore the Holder class which is similar to your suggestion. So, unless you propose a language addition (maybe in a C++ like way with adding&
at the end of a variable or on including an explicit ref keyword), this (and the array way) will probably be the only working solutions, IMO – Clements