14

If I have a list that I pass into a method to be populated, can I then reference that list variable in the class/method that did the passing, without having to return the list?

Here's an example, where a list with a single account ID is passed to a method, whose purpose is to recursively go through levels of child accounts:

public static void Get_Children(ID mainID, List<ID> ID_Group){        
    for(Account child :[SELECT ID, ParentID FROM Account WHERE ParentID = :mainID]){
        if(child.ParentId == mainID){ /*IF clause to make sure SOQL returned an actual account*/
            ID_Group.add(child.id);
            Get_Children(child.id, ID_Group);
        }
    }       
}

Note that the method doesn't return the list, it simply populates it. If I have a method in which the ID_Group list is declared, then pass that list into this method, and then look at the ID_Group list afterwards, will it have the data loaded in by this method?

2 Answers 2

22

In short the answer is yes! To understand why you need to understand the language concept of passing by value and passing by reference. The Apex developers guide has this to say about this concept here.

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.

So while the reference to the list is passed by value, in that changing what ID_Group points to (e.g. another list of Id's) does not change what the caller passed in. You can however change the contents of what it points to, thus you can add more items to the list for the caller to later discover.

4
  • As a matter of clarification, you can't pass an object by value.
    – sfdcfox
    Commented Oct 23, 2013 at 21:10
  • Correct, only the reference to the object is passed by value. The contents is up for grabs! :) Commented Oct 23, 2013 at 21:13
  • Andrew, thanks for your response! So tell me if I understand this correctly: The 'pointer' (aka reference) to the list is passed by value, meaning a separate copy of the list address is created within the called method. But while this copy and the original list address occupy separate locations in memory, they are after all the same address and point to the same location - where the list element data is stored. So I can succesfully use either reference to add or access list elements as needed.
    – smohyee
    Commented Oct 24, 2013 at 15:13
  • Yes thats more or less it, you can have many variables in different scopes pointing to the same list. Regardless of which variable or scope you edit the list the list is updated for them all, as the reference is shared. Commented Oct 24, 2013 at 16:03
1

Parameters in a method are always passed by reference.

public class TestByReference {

    Public static void TestByReference(List<String> strList){
        strList.add('TestByReference');
    }

}

List<String> strList = new List<String>();
strList.add('outSideMethod');
TestByReference.TestByReference(strList);
system.debug(strList);

OutPut : (outSideMethod, TestByReference)

1
  • This answer is wrong. The example given shows passing a reference to a collection object by value. See the answer by Andrew Fawcett for the correct answer.
    – mhenry1384
    Commented Nov 11 at 17:51

You must log in to answer this question.

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