Considerations for Passing Parameters
Not Started

Consider this code:

public class EmployeeController { public void main(){ String stringToUpdate = 'Original Value'; updateString(stringToUpdate); System.debug(stringToUpdate); } public void updateString(String stringToUpdate){ stringToUpdate = 'NEW VALUE'; } }

What value do you expect in stringToUpdate? If you said Original Value you'd be correct!

What about this code?

public class AccountController { public void main(){ Account acc = new Account(); acc.Name = 'Original Value'; updateName(acc); System.debug(acc.Name); } public void updateName(Account a){ a.Name = 'NEW VALUE'; } }

If you said the debug output is NEW VALUE, you'd be correct!

Confused? Here's why:

When a primitive datatype, like Integer, String, Boolean is passed into a method as an argument, they’re passed by value. Pass by value is a parameter passing mechanism that describes how arguments are passed into methods. In pass by value, a copy of the argument's value is passed to the method rather than the original data. This means that any changes made to the parameter inside the method will not affect the original value outside the method.

That's why in the first example, stringToUpdate retained its original value. If you wanted to retrieve the new value, you'd have to return it and reassign stringToUpdate:

public class EmployeeController { public void main(){ String stringToUpdate = 'Original Value'; stringToUpdate = updateString(stringToUpdate); System.debug(stringToUpdate); // Will now store 'NEW VALUE' } public String updateString(String stringToUpdate){ stringToUpdate = 'NEW VALUE'; return stringToUpdate; } }

Non-primitive datatypes are slightly different. They pass reference by value. With this mechanism, the method receives a copy of a reference to the original data, allowing it to indirectly access and modify it.

A reference is a pointer to the memory location of a variable within the computer executing the code. If you're interested, here is a deeper dive into the underlying computer science topic.

When passing a reference by value, a copy of the pointer to the original data is passed in, not the original data itself. That's why the AccountController code outputted NEW VALUE. A copy of acc's memory address was passed in, so when we modified the name, it modified it at that same memory address.

public class AccountController { public void main(){ Account acc = new Account(); acc.Name = 'Original Value'; updateName(acc); System.debug(acc.Name); } public void updateName(Account a){ a.Name = 'NEW VALUE'; } }

There's a gotcha here. This only works if we don't reinitialize the reference:

public class AccountController { public void main(){ Account acc = new Account(); acc.Name = 'Original Name'; changeName(acc); // original name is retained } private void changeName(Account a){ a = new Account(); a.Name = 'New Name'; } }

When a = new Account() runs, a is reassigned to a new reference and memory address, so the original copy that was passed in is lost. a.Name = 'New Name'; is now assigning the value at a different memory address than the one acc was pointing to. That's why the change is not reflected in the caller.

Challenge

Give passing references by value a try!

Create a class named CancellationService and define a method named cancelContract that accepts a Contract object as a parameter.

The method should update the contract object's status member variable to Cancelled. (with 2 Ls)

The following code will call your class:

public class ContractService { Contract activateContract; // how this was created is not important // activateContract.status is 'Active' currently CancellationService cancellationService = new CancellationService(); cancellationService.cancelContract(activateContract); // activateContract should now be cancelled }