12

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?

20

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.

  • As a matter of clarification, you can't pass an object by value. – sfdcfox Oct 23 '13 at 21:10
  • Correct, only the reference to the object is passed by value. The contents is up for grabs! :) – Andrew Fawcett Oct 23 '13 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 Oct 24 '13 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. – Andrew Fawcett Oct 24 '13 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)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.