This subsection covers variable declaration, data types, constants and enums, and type conversions. It also provides detail on rounding numbers and converting dates to and from strings, common tasks in business applications.
Apex is a strongly typed language. All variables must be declared before they’re referenced. At minimum, a variable declaration consists of the data type followed by the variable name. For example, Listing 4.2 is a valid statement.
Integer i;
The variable i
is declared to be an Integer. Apex does not require variables to be initialized before use, but doing so is good practice. The variable i
initially contains a null value.
Variable names cannot start with numbers or symbols, cannot contain two or more consecutive underscore characters, and must not conflict with Apex reserved words. These are special keywords used by the Apex language itself. The list of reserved words is available in the Force.com Apex Code Developer’s Guide.
Variable names are not case sensitive. Try defining two variables with the same name, one in uppercase and one in lowercase, to prove this, as in Listing 4.3. If you try to execute this code, you will receive a compilation error citing a duplicate variable.
Integer i;
String I;
In Apex, all data types are objects. There is no concept of a primitive type such as an int
in Java. Table 4.1 lists Apex’s standard atomic data types. These types contain a single value at a time or a null value.
A constant is a variable that cannot be modified after it has been initialized. It is declared using the final
keyword and can be initialized only in constructors, in initializers, or in the declaration itself.
An enum is a set of identifiers. Listing 4.4 provides an example of a constant as well as an enum. The constant is an Integer type; the enum is named MyConstants
and contains three members. The variable x
is initialized to the first member, and its data type is the enum itself, which can be thought of as a user-defined data type.
final Integer MAGIC_NUMBER = 42;
Enum MyConstants { One, Two, Three }
MyConstants x = MyConstants.One;
After it has been declared, an enum can be referenced in Apex code like any built-in data type. It can also be converted into an Integer from its zero-indexed position using its ordinal
method or into a String using its name
method.
The two ways to convert one data type to another are implicit and through conversion methods. Implicit conversion means that no method calls or special notation is required to convert one type into another. Conversion methods are functions that explicitly convert a value from one type to another type.
Implicit conversion is supported for numeric types and String types. For numbers, the rule is this: Integer → Long → Double → Decimal. Conversions can move from left to right without casting, as Listing 4.5 demonstrates.
Integer i = 123;
Long l = i;
Double d = l;
Decimal dec = d;
For Strings, ID and String are interchangeable, as shown in Listing 4.6. If conversion is attempted from String to ID but the String is not a valid ID, a System.StringException
is thrown.
String s = 'a0I80000003hazV';
ID id= s;
String s2 = id;
When implicit conversion is not available for a pair of types, you must use a conversion method. Data type objects contain a static conversion method called valueOf
. Most conversions can be handled through this method. Listing 4.7 is a series of statements that convert a string into the various numeric types.
String s = '1234';
Integer i = Integer.valueOf(s);
Double d = Double.valueOf(s);
Long l = Long.valueOf(s);
Decimal dec = Decimal.valueOf(s);
When a type conversion method fails, it throws a TypeException
. For example, when the code in Listing 4.8 executes, it results in an error: System.TypeException
: Invalid integer: 1234.56
.
String s = '1234.56';
Integer i = Integer.valueOf(s);
Rounding occurs when the fractional component of a Decimal or Double is dropped (round
), or when a Decimal is divided (divide
) or its scale (number of decimal places) reduced (setScale
). Apex has a set of rounding behaviors called rounding modes that apply in all three of these situations. By default, the rounding mode is HALF_EVEN
, which rounds to the nearest neighbor, or to the even neighbor if equidistant. For example, 0.5 rounds to 0, and 0.6 to 1. For the complete list of rounding modes, refer to the Force.com Apex Code Developer’s Guide at www.salesforce.com/us/developer/docs/apexcode/index.htm.
Listing 4.9 demonstrates the three operations that can cause rounding.
Decimal d = 123.456;
Long rounded = d.round(RoundingMode.HALF_EVEN);
Decimal divided = d.divide(3, 3, RoundingMode.HALF_EVEN);
Decimal reducedScale = d.setScale(2, RoundingMode.HALF_EVEN);
Strings can be converted to Date and Datetime types using the valueOf
conversion methods, but the string values you’re converting from must be in a specific format. For Date, the format is YYYY-MM-DD
; for Datetime, YYYY-MM-DD HH:MM:SS
, regardless of the locale setting of the user. Time does not have a valueOf
method, but you can create one with its newInstance
method, providing hours, minutes, seconds, and milliseconds. Listing 4.10 shows the creation of all three types.
Date d = Date.valueOf('2015-12-31'),
Datetime dt = Datetime.valueOf('2015-12-31 02:30:00'),
Time t = Time.newInstance(2,30,0,0);
Dates can be converted to strings through the String.valueOf
method. This applies a default format to the date values. If you want control over the format, Datetime has a format
method that accepts a Date pattern. This pattern follows the SimpleDateFormat
pattern found in the Java API, which is documented at the following URL: http://download.oracle.com/javase/1.4.2/docs/api/java/text/SimpleDateFormat.html. For example, the code in Listing 4.11 outputs Thu Dec 31, 2020
.
Datetime dt = Datetime.valueOf('2020-12-31 00:00:00'),
System.debug(dt.format('E MMM dd, yyyy'));
18.220.237.24