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?
Pass by Value: It is a process in which the function parameter values are copied to another variable and instead this object copied is passed. This is known as call by Value. Pass by Reference: It is a process in which the actual copy of reference is passed to the function. This is called by Reference.
Java always passes arguments by value, NOT by reference.
The usual idiom I've seen for pass-by-reference in Java is to pass a single-element array, which will both preserve run-time type-safety (unlike generics which undergo erasure) and avoid the need to introduce a new class.
public static void main(String[] args) { String[] holder = new String[1]; // variable optimized away as holder[0] holder[0] = "'previous String reference'"; passByReference(holder); System.out.println(holder[0]); } public static void passByReference(String[] someString) { someString[0] = "'new String reference'"; }
To answer your question:
Where can this fail?
this
new
...and possibly others. Basically, your ref
keyword must only be usable if the parameter source is a non-final field or local variable. Any other source should generate a compilation error when used with ref
.
An example of (1):
final String s = "final"; passByReference(ref s); // Should not be possible
An example of (2):
passByReference(ref this); // Definitely impossible
An example of (3):
passByReference(ref toString()); // Definitely impossible passByReference(ref new String("foo")); // Definitely impossible
An example of (4):
passByReference(ref "literal"); // Definitely impossible
And then there are assignment expressions, which seem to me like something of a judgement call:
String s; passByReference(ref (s="initial")); // Possible, but does it make sense?
It's also a little strange that your syntax requires the ref
keyword for both the method definition and the method invocation. I think the method definition would be sufficient.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With