Why use Apex Properties vs normal getter & setter?
- johnsontitus
- May 9, 2020
- 4 min read
Updated: May 10, 2020
An Apex property is similar to a variable.
Use case # 1:
Properties can be used to validate data before a change is made.
Eg:
<apex:page standardController="Account" recordSetVar="accounts" extensions="MyControllerExtension"> <apex:pageBlock > <apex:pageBlockTable value="{!accounts}" var="acc"> <apex:column value="{!acc.id}"/> <apex:column value="{!acc.name}"/> </apex:pageBlockTable> </apex:pageBlock> </apex:page>
public with sharing class MyControllerExtension { private ApexPages.StandardSetController setController; public MyControllerExtension(ApexPages.StandardSetController setController) { this.setController = setController; } public List<Account> accounts{ get{ List<Account> accts; if(accounts == null){ accts = [SELECT Id, Name FROM Account Limit 5 ]; } return accts; }
set; } }
Use case # 2:
To prompt an action when data is changed (such as altering the value of other member variables)
Eg:
public class BasicProperty { String msg = 'Hello world'; public integer prop { get { return prop; } set { prop = value; If(value == 5){ msg = 'Hello world changed'; System.debug(msg); } } } }
BasicProperty bp = new BasicProperty(); bp.prop = 5;
Use case # 3:
To expose data that is retrieved from some other source (such as another class).
Lets say you have a trigger on a Contact that needs information from our mostly static MyObject__c and then the Contact trigger then updates a Case. The Case trigger also need information from the MyObject__c. Normally this would require two SOQL queries even if it was in a utility class. We can use some of the built-in functionality in Apex to overload a static variable.
public with sharing class MyObjectUtils { public static List<MyObject__c> myObjectList { get { if (myObjectList == null) { myObjectList = [ select Name from MyObject__c ]; } return myObjectList; } set; } public static Map<String, MyObject__c> myObjectMap { get { if (myObjectMap == null) { myObjectMap = new Map<String, MyObject__c>(); for (MyObject__c obj: myObjectList) { myObjectMap.put(obj.Name, obj); } } return myObjectMap; } set; } }
Property definitions include one or two code blocks, representing a get accessor and a set accessor:
The code in a get accessor executes when the property is read.
The code in a set accessor executes when the property is assigned a new value.
If a property has only a get accessor, it is considered read only. If a property has only a set accessor, it is considered write only. A property with both accessors is considered read-write.
Declaring a property
You declare a variable as <access modifier> <data type> <variable name>
Property is declared as:
access_modifier return_type property_name { get { //Get accessor code block } set { //Set accessor code block } }
Eg:
public class BasicProperty { public integer prop { get { return prop; } set { prop = value; } } }
Note:
The get accessor must end in a return statement. It should return value of data type defined for the property. In this case integer.
When the set accessor is invoked, the system passes an implicit argument to the setter called value of the same data type as the property.
Calling the get and set accessor of the property - prop:
BasicProperty bp = new BasicProperty(); bp.prop = 5; // Calls set accessor System.assertEquals(5, bp.prop); // Calls get accessor
Automatic Properties:
Properties do not require additional code in their get or set accessor code blocks. Instead, you can leave get and set accessor code blocks empty to define an automatic property. public class AutomaticProperty { public integer MyReadOnlyProp { get; } public double MyReadWriteProp { get; set; } public string MyWriteOnlyProp { set; } }
AutomaticProperty ap = new AutomaticProperty();
ap.MyReadOnlyProp = 5; // This produces a compile error: not writable
ap.MyReadWriteProp = 5; // No error
System.assertEquals(5, ap.MyWriteOnlyProp); // This produces a compile error: not readable
Getter & Setter:
Use getters/setters to access private variables
Getter Methods
Getter methods return values from a controller.
Every value that is calculated by a controller and displayed in a page must have a corresponding getter method, including any Boolean variables.
For example, in the below eg, the controller includes a getAccount method. This method allows the page markup to reference the account member variable in the controller class with {! } notation. The value parameter of the <apex:inputField> tag uses this notation to access the account, and dot notation to display the account's name. Getter methods must always be named getVariable.
Eg:
public class MyController { private final Account account; public MyController() { account = [SELECT Id, Name, Site FROM Account WHERE Id = :ApexPages.currentPage().getParameters().get('id')]; } public Account getAccount() { return account; } public PageReference save() { update account; return null; } }
<apex:page controller="myController" tabStyle="Account"> <apex:form> <apex:pageBlock title="Congratulations {!$User.FirstName}"> You belong to Account Name: <apex:inputField value="{!account.name}"/> <apex:commandButton action="{!save}" value="save"/> </apex:pageBlock> </apex:form> </apex:page>
Setter Methods
Setter methods pass user-specified values from page markup to a controller.
Any setter methods in a controller are automatically executed before any action methods. For example, the following markup displays a page that implements basic search functionality for Leads. The associated controller includes getter and setter methods for the search box input, and then uses the search text to issue a SOSL query when the user clicks Go!. Although the markup doesn’t explicitly call the search text setter method, it executes before the doSearch action method when a user clicks the command button:
<apex:page controller="theController"> <apex:form> <apex:pageBlock mode="edit" id="block"> <apex:pageBlockSection> <apex:pageBlockSectionItem> <apex:outputLabel for="searchText">Search Text</apex:outputLabel> <apex:panelGroup> <apex:inputText id="searchText" value="{!searchText}"/> <apex:commandButton value="Go!" action="{!doSearch}" rerender="block" status="status"/> </apex:panelGroup> </apex:pageBlockSectionItem> </apex:pageBlockSection> <apex:actionStatus id="status" startText="requesting..."/> <apex:pageBlockSection title="Results" id="results" columns="1"> <apex:pageBlockTable value="{!results}" var="l" rendered="{!NOT(ISNULL(results))}"> <apex:column value="{!l.name}"/> <apex:column value="{!l.email}"/> <apex:column value="{!l.phone}"/> </apex:pageBlockTable> </apex:pageBlockSection> </apex:pageBlock> </apex:form> </apex:page>
public class theController { String searchText; List<Lead> results; public String getSearchText() { return searchText; } public void setSearchText(String s) { searchText = s; } public List<Lead> getResults() { return results; } public PageReference doSearch() { results = (List<Lead>)[FIND :searchText RETURNING Lead(Name, Email, Phone)][0]; return null; } }

Comments