7

I’ve noticed that the contents of an object variable can be altered when the variable is passed through a void method, while the value of a primitive variable cannot be.

For example, the following logs 'old string'

public void StringTest(String s){
    s = 'new string';
}

String str = 'old string';
StringTest(str);
System.debug(str); // logs 'old string'

... while the following logs 'new string'

public class SomeClass{
    public String st;
}

public void ClassTest(SomeClass c){
    c.st = 'new string';
}

SomeClass sc = new SomeClass();
sc.st = 'old string';
ClassTest(sc);
System.debug(sc.st); // logs 'new string'

Why does it work this way? Apologies if this is a super basic concept. I am self-taught and therefore know nothing.

1
  • 3
    It is a basic concept called passing by reference vs passing by value. But don't worry about not knowing it, you'll learn. Commented May 13, 2016 at 4:33

2 Answers 2

13

This is because objects and primitives behave differently in apex.

“In Apex, all primitive data type arguments, such as Integer or String, are passed into methods by value. This means that any changes to the arguments exist only within the scope of the method. When the method returns, the changes to the arguments are lost.

Non-primitive data type arguments, such as sObjects, are also passed into methods by value. This means that when the method returns, the passed-in argument still references the same object as before the method call, and can’t be changed to point to another object. However, the values of the object’s fields can be changed in the method.”

See also: Passing Parameters By Reference and By Value in Apex

1
  • 6
    It is a pity that the documentation mentions string here, as in reality strings are passed by reference (as otherwise large amounts of data would have to be copied). Its the immutability of strings that ensures the string can't be altered - but same end result.
    – Keith C
    Commented May 13, 2016 at 8:30
0

This code exhibits no difference in how the language treats string and your user defined object. The difference is in the code itself.

The first piece of code tries to replace the whole value (which is a reference). This has no effect on the calling code, because it's pass-by-value.

The second piece of code mutates part of the object. Since it's a reference type, that change is visible through all references to the same object. If you assigned a new value to c inside the function, you wouldn't see the change outside the function.

For immutable types, such a string, there is no way to change only part of the object, so it's impossible to write code that behaves like second example.

This has nothing to do with "primitives", which is a pretty useless designation in the first place. You should rather think about value-types and reference-types.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .