Variables are the most basic of all programming concepts but are the foundation upon which everything else is built. So what is a Variable? A variable is a store for some data that can change (or vary) over time. If you have done algebra at school you will be familiar with variables such as x = 8, which is a variable called x whose value is 8. Variables are defined to allow us to hold and manipulate data within the system.
Variables in Apex
As already we have learned that Salesforce Apex is a strongly typed language like OOPS, we have to define the data type for the variable we are instantiating. Salesforce has a number of different data types they are. The first and most basic of these data types are known as primitive data types.
Primitive data types are the foundational data types that are used to hold data we are most familiar with.
DataType variableName = value;
It is common practice to use what is called camel case in naming your variables in Apex, as shown with variableName rather than variable_name or another structure. Below we will detail each primitive data type, how to declare a variable in that type and when you might use the type.
A Blob is a set of binary data stored in a single object, for example, it can be the response from a web services request or the body of an attachment to an email. You can create a Blob by either assigning it the value of an attachment or document body or through converting a string into a Blob object as shown below:
Blob myDataBlob = Blob.valueOf('my text to convert');
Blob values are also commonly used in processes where you are either encrypting to a Blob or decrypting from a Blob to add some additional security to a set of data. We have also called our first method here, valueOf(). In Apex, you call methods on a class using the dot notation, Blob.valueOf(), and pass in any parameters between the parentheses. We will cover this in more detail later in Chapter 9. Apex Classes where we discuss classes and methods, but it is important here to understand that we are calling the valueOf method on the Blob class and passing in a string parameter (more on strings below).
Boolean values are simply true or false values used for logical processing or holding some state which is either on or off. For example, you may bind a checkbox on a page to a Boolean value to store whether that checkbox is checked or not, and default it to false:
Boolean isChecked = false;
In Apex, unlike some other languages, Boolean variables can hold 3 different states, true, false, and null. It is a best practice to always declare a Boolean to be in either a true or false state by default rather than leave it to default to null as this will cause a NullPointerException when attempting to use in in comparisons and your code will fail. We will discuss the null value and NullPointerException in more detail later in this chapter.
The Date data type stores information on a particular day without holding any information on the time of day. An example of this would be someone’s birthdate or the date on which a sales opportunity is expected to close. Date and its related primitives, DateTime, and Time are slightly different from other primitives in that they must be created using a static system method, like Blob. We will cover what a static method is in more detail later, but for now, it is only important to know we define a Date using the following syntax:
Date christmas = Date.newInstance(2020, 12, 25); Date todaysDate = Date.today(); Date newYearsEve = Date.parse('31/12/2020');
We can see here we have defined 3 different dates using 3 different static system methods, newInstance which takes in the year, month, and day parameters, today which returns today’s date, and parse which takes in date as some text. You can see here that the date for New Year’s Eve is written in the dd/mm/yyyy format used in Europe. This method is contextually aware and will use the user’s local date format.
Datetime is a primitive holding both a date and a particular time on that date, commonly used for either time-dependent information such as appointment time, or for storing auditing and logging information such as the day and time on which an action occurred. Similar to Date you create Datetime values using static system methods, the two most common of which from my experience are:
Datetime thisMoment = Datetime.now(); Datetime meetingStart = Datetime.newInstance(2020, 9, 1, 9, 30, 0);
The first method defines a variable thisMoment which is assigned the value of the date and time (including milliseconds) of when that variable is created. The second line defines a variable meetingStart that holds the value 9:30 am on the 1st of September 2020.
The Decimal data type is used for storing numerical data including decimals, but that have a fixed scale that can either be set explicitly or from the data creating the variable. Decimal data is mainly used when dealing with currency fields that will return data in Apex as a decimal.
Decimal itemCost = 1.99; Decimal percentageComplete = 15.266543;
The itemCost variable has the scale set to 2 decimal places and the percentage complete variable to 6 decimal places. If we are dealing with any sort of calculation where we require specific accuracy, we should use the Decimal type, however, it is important to be aware of the scale of the data to avoid rounding errors.
Similar to Decimal is Double, again a number involving a decimal point, but in this instance a 64-bit number with a maximum value of 2^63 -1 and a minimum value of -2^63 (that is a value between positive 9 quintillion and negative 9 quintillions (approximately). Doubles variables however are not as accurate for storing values as variables of the Decimal type and so we should avoid them for any financial calculations.
Double goldenRatio = 1.61803398875;
This is a special data type available to Apex and Salesforce programmers and is the 18 character Id for a particular record. Salesforce verifies the Id at runtime when a variable of type Id is assigned a value and will error if the value is invalid. It will also convert a 15 character Id into an 18 character Id as part of this process.
ID accountId = '0013z00002PNSXtAAP';
The Integer data type can hold any whole number between 2,147,483,647 and -2,147,483,648. Integers variables are used a lot as counting variables and in loops to help keep track of progress through a collection. Integer total = 25; Long A Long value is a very big integer, which is a value without a decimal point between 2^63 – 1 and -2^63 (again between positive and negative 9 quintillions roughly). In my work with Salesforce, I have not come across many instances where I have needed to use the Long data type although this just may be because my numbers haven’t been big enough. If you do not need over 2,147,483,647 or less than -2,147,483,648 you should use the Integer data type, otherwise, you can define a Long in the following way:
Long revenue = 3147483647L;
All other data types in Apex, primitives included, inherit from the Object data type. You can cast variables of the Object data type to a more specific data type as long as the underlying data in that variable is of a compatible type. Casting changes the data from a variable from one type into another compatible data type, for example from an Integer to an Object or from an Object holding compatible data to an Integer. You can see an example of declaring a variable of an Object data type with Integer data and then casting to an Integer type variable below:
Object myData = 1618; Integer myIntegerData = (Integer)myData;
You cast data between types by placing the new data type in parentheses before the data or name of the variable being cast. The Object data type is typically used when you are unsure of the type of data you are receiving, for example in a web service callout before being cast to another data type.
The String data type is for any collection of characters enclosed within single quotation marks such as:
String myName = ‘Prasanth'; String empty = ''; String greeting = 'Hello ' + myName;
In the final variable, we declare a variable called greeting. You can see we are able to concatenate strings together using the + symbol so that greeting has the value Hello Prasanth. The variable we defined called empty is the empty string, which is a string containing no characters with length 0. It is important to note that this is different from null which is a string with no characters and not an empty string. We will discuss null in more detail below. You may be wondering how we can include single quotations in our strings given that we enclose the string in single quotations.
Time Our final primitive data type is Time which is very similar to Date and DateTime and represents a timestamp that is not dependent on a day. You define a Time type variable using the static newInstance method as shown below
Time coffeeTime = Time.newInstance(10, 35, 23, 400);
This defines the time 10:35:23:400 (10:35 am, 23 seconds, and 400 milliseconds). This method assumes you are using the Coordinated Universal Time (UTC) timezone1.
A NullPointerException is one of the most common exceptions seen in Apex and is where you ask the system to perform some action on a value that does not exist i.e. is null. Using our example of my none existent sisters, if you wanted to get the month portion of my oldest sister’s birthday, you would get a NullPointerException, that is we are trying to find the month portion of a date that is non-existent, i.e. null.
We now understand how to define variables so that we can work with data that might change over time, but how about data that we know is going to stay fixed? An example may the maximum number of items we want to display in a list or the text for a welcome message. You declare a constant variable in Apex by prefixing the declaration with the keywords static final. The use of both the static and final keywords means that the constant can only be defined or assigned a value where it is declared or in a static block. We will discuss static blocks in more detail later when discussing classes.
static final String GREETING = 'Hello ‘; static final Integer MAX_ITEMS = 2000; static final Double PI = 3.14;
You may have noticed that I have named the constants GREETING, MAX_ITEMS, and PI rather than greeting, maxItems, and pi. This a particular naming convention for constants popular in languages like Apex, C#, and Java. It serves no technical purpose (the lowercase names work just as well) but for readability, I would advise following this convention when working with constants.