---
title: "Static in Apex Salesforce"
url: "https://blog.beyondthecloud.dev/blog/static-in-apex"
author: "Piotr Gajek"
published: "2023-07-02"
updated: "2025-02-27"
tags: "apex, static, static in apex, static method apex, static variable apex"
---

# Static in Apex Salesforce

By [Piotr Gajek](https://blog.beyondthecloud.dev/author/piotr-gajek.md), July 2, 2023

Hello devs,

**Static** variables are a key aspect of programming that can significantly enhance code functionality and efficiency.  
In this post, I’ll provide a brief introduction to static variables, shedding light on their importance in apex development.

## Introduction

Let’s start with definitions:

> The `static` keyword is a non-access modifier used for methods and attributes. Static methods/attributes can be accessed without creating an object of a class.
> 
> The `static` keyword is used to associate a variable or method with a class rather than a specific instance of the class.

But what does it all mean?

Talk is cheap, show me the code!

**Static variable/method**

_Variable/method associated with a class_

```java
public class Calculator {
    public static Double sumOfAll = 0;

    public static Double add(Double a) {
        sumOfAll += a;
        return sumOfAll;
    }
}

System.debug(Calculator.sumOfAll); // 0.0

Calculator myCalculator = new Calculator();
System.debug(myCalculator.sumOfAll); 
// error: Static field cannot be referenced from a non static context: sumOfAll from the type myCalculator

Calculator.add(2);
System.debug(Calculator.sumOfAll); // 2.0

Calculator.add(4);
System.debug(Calculator.sumOfAll); // 6.0

Calculator.add(8);
System.debug(Calculator.sumOfAll); // 14.0
```

**Instance variable/method**

_Variable/method associated with a specific instance of the class_

```java
public with sharing class Calculator {
    private Double a;
    private Double b;

    public Calculator(Double a, Double b) {
        this.a = a;
        this.b = b;
    }

    public Double add() {
        return a + b;
    }

    public Double subtract() {
        return a - b;
    }
}

System.debug(Calculator.a); // error: Variable does not exist: a
System.debug(Calculator.b); // error: Variable does not exist: b

Calculator calculator1 = new Calculator(128, 64);

System.debug(calculator1.add()); // 192.0
System.debug(calculator1.subtract()); // 64.0

Calculator calculator2 = new Calculator(256, 8);

System.debug(calculator2.add()); // 264.0
System.debug(calculator2.subtract()); // 248.0
```

## Consideration

* The `static` keyword can be only used in the outer class and cannot be a part of the inner class.

> 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. \~ Salesforce

```java
public class MyOuterClass {
    public static Boolean isActive = true; // valid

    public class MyInnerClass {
        public static Boolean isActive = true; // error: static can only be used on fields of a top level type
    }
}
```

* `Static` variables are created only when a class is loaded or used. Variables associated with a specific instance of the class are created with every object instantiated from the class.
* `Static` variables are reset in Unit Tests. There is [Salesforce Idea](https://ideas.salesforce.com/s/idea/a0B8W00000GdX0YUAV/remember-static-variables-set-during-testsetup-annotated-methods) to change this behavior.
* `Static` does NOT require an instance of the class.

As was mentioned in the introduction:

> `static` keyword makes a variable or method **associated with a class rather than a specific instance of the class**.

```java
public class MyClass {
    public static Boolean isActive = true;
}

System.debug(MyClass.isActive); // valid

MyClass myClass = new MyClass();
System.debug(MyClass.isActive); // error: Static field cannot be referenced from a non static context: isActive from the type MyClass
```

* `Static` is only in the scope of the transaction and will not persist longer than that transaction. `Static` values cannot be shared between multiple execution contexts. To save state between transaction, values need to be saved to the database e.g., as an object record, platform cache, or custom settings).

> 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. \~ Salesforce

`Static` lifetime can be consider as the main benefit of `static`. It allows you to create a simple [singleton](https://refactoring.guru/design-patterns/singleton). A variable will be accessible throughout the transaction. More details in the [use case](#use-cases) section.

Its behavior can be modified using getters.

A simple cache approach:

```java
public class CurrentUserInfo {
    public static User userDetails = [SELECT Id, Name, Email FROM User WHERE Id = :UserInfo.getUserId()];
}

User currentUser = null;

currentUser = CurrentUserInfo.userDetails;
Assert.areEquals(1, Limits.getQueries(), 'Only 1 SOQL query was consumed');

currentUser = CurrentUserInfo.userDetails;
Assert.areEquals(1, Limits.getQueries(), 'Only 1 SOQL query was consumed');

currentUser = CurrentUserInfo.userDetails;
Assert.areEquals(1, Limits.getQueries(), 'Only 1 SOQL query was consumed');

currentUser = CurrentUserInfo.userDetails;
Assert.areEquals(1, Limits.getQueries(), 'Only 1 SOQL query was consumed');
```

```java
public class CurrentUserInfo {
    public static User userDetails {
        get {
            return [SELECT Id, Name, Email FROM User WHERE Id = :UserInfo.getUserId()];
        }
    }
}

User currentUser = null;

currentUser = CurrentUserInfo.userDetails;
Assert.areEquals(1, Limits.getQueries(), '1 SOQL query was consumed');

currentUser = CurrentUserInfo.userDetails;
Assert.areEquals(2, Limits.getQueries(), '2 SOQLs query were consumed');

currentUser = CurrentUserInfo.userDetails;
Assert.areEquals(3, Limits.getQueries(), '3 SOQLs query were consumed');

currentUser = CurrentUserInfo.userDetails;
Assert.areEquals(4, Limits.getQueries(), '4 SOQLs query were consumed');
```

* `Static` cannot be accessed through an instance of the class.

```java
public class MyClass {
    public static Boolean isActive = false;
}

System.debug(MyClass.isActive); // false

MyClass example1 = new MyClass();
System.debug(example1.isActive); // error: Variable does not exist: isActive
```

* `Static` methods cannot use `this` keyword because `static` is NOT associated with a specific instance of a class.

```java
public class MyClass {
    public Boolean isActive = false;

    public static Boolean getIsActive() {
        return this.isActive; // error: This cannot be referenced in a static context
    }
}
```

## Static vs Non-static

| Scenario      | Static                                                     | Non-Static (Instance)                                                                           |
| ------------- | ---------------------------------------------------------- | ----------------------------------------------------------------------------------------------- |
| Ownership     | Belongs to the class                                       | Belongs to the instance (new) of the class                                                      |
| Usage         | Can ONLY be invoked from the class MyClass.staticVariable; | Can ONLY be called form an instance of the class new MyClass().nonStaticVariable;               |
| Combined with | ONLY static methods; this cannot be used                   | Static and non-static can be used; this can be used                                             |
| Memory        | Initialized only when a class is loaded                    | Created with every object instantiated (new is called) from the class in which they’re declared |

## Best practices

While static variables can be useful for sharing data, it’s generally recommended to avoid excessive reliance on global state. Global states can make code harder to understand, maintain, and test.

## Use Cases

### Utils

> A `static` method is used as a utility method, and it never depends on the value of an instance member variable. \~ Salesforce

#### RecordTypesInfo.cls

As you can see in the code below, RecordType information will be stored in `static` variables, making it accessible across all Apex classes within the entire transaction.

```java
public with sharing class RecordTypesInfo {
    private static Map<sObjectType, Map<String, Schema.RecordTypeInfo>> recordTypesInfo = new Map<sObjectType, Map<String, Schema.RecordTypeInfo>>();

    public static Schema.RecordTypeInfo get(SObjectType objectType, String recordTypeDeveloperName) {
        Map<String, Schema.RecordTypeInfo> recordTypesInfoForSObject = recordTypesInfo?.get(objectType);

        if (recordTypesInfoForSObject == null) {
            recordTypesInfoForSObject = objectType.getDescribe(SObjectDescribeOptions.DEFERRED).getRecordTypeInfosByDeveloperName();
            recordTypesInfo.put(objectType, recordTypesInfoForSObject);
        }

        return recordTypesInfoForSObject?.get(recordTypeDeveloperName);
    }
}

Id partnerAccountRecordTypeId = RecordTypesInfo.get(Account.SObjectType, 'Partner');
Id customerAccountRecordTypeId = RecordTypesInfo.get(Account.SObjectType, 'Customer');
```

### Consts

`Apex Consts`

It is a common approach to keep constant variables `static`. As mentioned above, "static variables are initialized once," which allows for saving Apex heap size.

[Constants in Apex](https://beyondthecloud.dev/blog/constants-in-apex)

[Consts framework (github)](https://github.com/beyond-the-cloud-dev/apex-consts)

### Singleton

> 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. \~ Salesforce

Let’s take a class from [Constants in Apex](https://beyondthecloud.dev/blog/constants-in-apex).

```java
public class ContactConsts {
    public static final ContactConsts INSTANCE = new ContactConsts();

    private ContactConsts() {}

    public final String API_NAME = Contact.sObjectType.getDescribe().getName();

    public final LeadSource LEAD_SOURCE = new LeadSource();

    private class LeadSource {
        public final String OTHER = 'Other';
        public final String PARTNER_REFERRAL = 'Partner Referral';
        public final String PHONE_INQUIRY = 'Phone Inquiry';
        public final String PURCHASED_LIST = 'Purchased List';
        public final String WEB = 'Web';
    }
}

// All variables will be loaded once
System.debug(ContactConsts.INSTANCE.API_NAME);
```

### Recursive Triggers

> 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 \~ Salesforce

A lot of trigger frameworks use `static` variables to store information about:

* disabled triggers
* disable trigger handlers
* or trigger recursion

## Summary

Static variables are associated with the class rather than a specific instance. They are created when a class is loaded and persist throughout the transaction. Static variables are useful for maintaining state, creating utility methods, holding constant values, and implementing the singleton pattern. However, excessive use of static variables can lead to code complexity and difficulty in testing and maintenance. It is important to use static variables judiciously and consider the overall design and architecture of your code.

I hope this provides a comprehensive overview of static variables in Apex development. If you have any further questions, feel free to ask!

## Resources

* [Static and Instance Methods, Variables, and Initialization Code](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex%5Fclasses%5Fstatic.htm)
* [Best practice for using static variables](https://salesforce.stackexchange.com/questions/371936/best-pratice-for-using-static-variables)
