Static and Instance Methods, Variables, and Initialization Code
Characteristics
Static methods, variables, and initialization code have these characteristics.
- They’re associated with a class.
- They’re allowed only in outer classes.
- They’re initialized only when a class is loaded.
- They aren’t transmitted as part of the view state for a Visualforce page.
Instance methods, member variables, and initialization code have these characteristics.
- They’re associated with a particular object.
- They have no definition modifier.
- They’re created with every object instantiated from the class in which they’re declared.
Local variables have these characteristics.
- They’re associated with the block of code in which they’re declared.
- They must be initialized before they’re used.
The following example shows a local variable whose scope is the duration of the if code block.
Boolean myCondition = true;
if (myCondition) {
integer localVariable = 10;
}
Using Static Methods and Variables
You can use static methods and variables only with outer classes. Inner classes have no static methods or variables. A static method or variable doesn’t require an instance of the class in order to run.
Before an object of a class is created, all static member variables in a class are initialized, and all static initialization code blocks are executed. These items are handled in the order in which they appear in the class.
A static method is used as a utility method, and it never depends on the value of an instance member variable. Because a static method is only associated with a class, it can’t access the instance member variable values of its class.
A static variable is static only within the scope of the Apex transaction. It’s not static across the server or the entire organization. The value of a static variable persists within the context of a single transaction and is reset across transaction boundaries. For example, if an Apex DML request causes a trigger to fire multiple times, the static variables persist across these trigger invocations.
To store information that is shared across instances of a class, use a static variable. All instances of the same class share a single copy of the static variable. For example, all triggers that a single transaction spawns can communicate with each other by viewing and updating static variables in a related class. A recursive trigger can use the value of a class variable to determine when to exit the recursion.
Suppose that you had the following class.
public class P {
public static boolean firstRun = true;
}
A trigger that uses this class could then selectively fail the first run of the trigger.
trigger T1 on Account (before delete, after delete, after undelete) {
if(Trigger.isBefore){
if(Trigger.isDelete){
if(p.firstRun){
Trigger.old[0].addError('Before Account Delete Error');
p.firstRun=false;
}
}
}
}
A static variable defined in a trigger doesn't retain its value between different trigger contexts within the same transaction, such as between before insert and after insert invocations. Instead, define the static variables in a class so that the trigger can access these class member variables and check their static values.
A class static variable can’t be accessed through an instance of that class. If class MyClass has a static variable myStaticVariable, and myClassInstance is an instance of MyClass, myClassInstance.myStaticVariable isn’t a legal expression.
The same is true for instance methods. If myStaticMethod() is a static method, myClassInstance.myStaticMethod() isn’t legal. Instead, refer to those static identifiers using the class: MyClass.myStaticVariable and MyClass.myStaticMethod().
public static void method() {
String Database = '';
Database.insert(new Account());
}
An inner class behaves like a static Java inner class, but doesn’t require the static keyword. An inner class can have instance member variables like an outer class, but there’s no implicit pointer to an instance of the outer class (using the this keyword).
Using Instance Methods and Variables
Instance methods and member variables are used by an instance of a class, that is, by an object. An instance member variable is declared inside a class, but not within a method. Instance methods usually use instance member variables to affect the behavior of the method.
Suppose that you want to have a class that collects two-dimensional points and plots them on a graph. The following skeleton class uses member variables to hold the list of points and an inner class to manage the two-dimensional list of points.
public class Plotter {
// This inner class manages the points
class Point {
Double x;
Double y;
Point(Double x, Double y) {
this.x = x;
this.y = y;
}
Double getXCoordinate() {
return x;
}
Double getYCoordinate() {
return y;
}
}
List<Point> points = new List<Point>();
public void plot(Double x, Double y) {
points.add(new Point(x, y));
}
// The following method takes the list of points and does something with them
public void render() {
}
}
Using Initialization Code
Instance initialization code is a block of code in the following form that is defined in a class.
{
//code body
}
The instance initialization code in a class is executed each time an object is instantiated from that class. These code blocks run before the constructor.
If you don’t want to write your own constructor for a class, you can use an instance initialization code block to initialize instance variables. In simple situations, use an ordinary initializer. Reserve initialization code for complex situations, such as initializing a static map. A static initialization block runs only one time, regardless of how many times you access the class that contains it.
Static initialization code is a block of code preceded with the keyword static.
static {
//code body
}
Similar to other static code, a static initialization code block is only initialized one time on the first use of the class.
A class can have any number of either static or instance initialization code blocks. They can appear anywhere in the code body. The code blocks are executed in the order in which they appear in the file, just as they are in Java.
You can use static initialization code to initialize static final variables and to declare information that’s static, such as a map of values. For example:
public class MyClass {
class RGB {
Integer red;
Integer green;
Integer blue;
RGB(Integer red, Integer green, Integer blue) {
this.red = red;
this.green = green;
this.blue = blue;
}
}
static Map<String, RGB> colorMap = new Map<String, RGB>();
static {
colorMap.put('red', new RGB(255, 0, 0));
colorMap.put('cyan', new RGB(0, 255, 255));
colorMap.put('magenta', new RGB(255, 0, 255));
}
}
Versioned Behavior Changes
In API version 50.0 and later, scope and accessibility rules are enforced on Apex variables, methods, inner classes, and interfaces that are annotated with @namespaceAccessible. For accessibility considerations, see NamespaceAccessible Annotation. For more information on namespace-based visibility, see Namespace-Based Visibility for Apex Classes in Second-Generation Packages.