Static Methods and Variables
Not Started

What if I told you not every class needs to be instantiated? I promised not to lie, but I did it again!

I have even worse news, we need to refactor our EmployeeController a little more. It’s not a good idea to hardcode data. Hardcoding is where we set variables in our code in a way that would make it impossible to change without modifying the code itself.

We hardcoded currentYear by assigning it the Integer 2023 in the previous examples. What happens on January 1st, 2024? The code will still be referencing 2023! We shouldn’t have to update this code every year for it to continue working as expected. There is a better way to get the current year.

Apex provides an array of built-in classes, you’ve interacted with some of them already, like Strings, Integers, and Booleans. Those are classes, too! Apex provides another called System. This class has a variety of pre-built methods. We are going to use a method called today() which returns today’s date as a Date datatype.

Date is a primitive datatype that has its own class too. One of the methods available in the Date class is called year(). We can use this to our advantage by combining these to get the current year. Adding this change to the EmployeeController gives us:

public class EmployeeController { Date todaysDate = System.today(); // provides today’s date Integer currentYear = todaysDate.year(); // this dissects the year value from the Date Employee jerryEmployee = new Employee('Jerry', 2015); Integer jerryYearsOfEmployment = jerryEmployee.calculateTenure(currentYear); Employee elaineEmployee = new Employee('Elaine', 2018); Integer elaineYearsOfEmployment = elaineEmployee.calculateTenure(currentYear); }

This allows us to dynamically set the current year without hardcoding. If you have a good eye, you’ll notice a few things are different here. Were you expecting to see this instead?

System sfdcSystem = new System(); Date todaysDate = sfdcSystem.today(); Integer thisYear = todaysDate.year();

If so, I don’t blame you. I’ve been keeping secrets from you. 😥

Less dramatically - not every class needs to be initialized to bring value. So far, we’ve learned about member variables and member methods that belong to an instance of a class, the object. These types of variables and methods can only exist if the object exists. They’re created and “brought to life” (memory is allocated for them on the computer disk) when an object is created using the new operator.

Static methods and variables don’t have these characteristics. They rely on the existence of the class, not the object. So we can use the dot operator to access these types of methods and variables without creating an object. Static variables are initialized when the class is referenced by a running piece of code. We can only declare variables and methods as static on outer classes.

That’s why with the System class, we don’t have to use the new operator to create a System object. Here’s an illustration with a new class called OpportunityUtils that declares static variables and static methods.

public class OpportunityUtils { private static final String STAGE_WON = 'Opportunity Won'; public static Integer today = System.today(); public static String getStageWonLabel(){ return STAGE_WON; } }

And we’d reference the class's static attributes and methods using the ClassName.methodName() or ClassName.attribute syntax:

public class ClosedOpportunityController { Date todayDate = OpportunityUtils.today; String closedWonLabel = OpportunityUtils.STAGE_WON; String closedWonLabelFromMethod = OpportunityUtils.getStageWonLabel(); }

Static variables are often used to keep track of state with Apex. Static methods are typically used to perform more generic operations on data that’s not tied to an object.

Challenge

Consider the following code exists in the codebase:

public class LeadUtils { public static final String OPEN_STATUS = 'Open'; public static final String QUALIFIED_STATUS = 'Qualified'; public static String getDefaultRating(){ return 'Warm'; } }

Create a class name Lead and declare 3 String member variables that should all be initialized using LeadUtils. The member variables should be named openStatus, qualifiedStatus, and defaultRating.