How to Use Marker Interfaces in Salesforce Apex (With Practical Examples)

By | June 27, 2026

If you’ve spent time in the Java ecosystem, you’ve likely come across marker interfaces. Surprisingly, this design pattern is rarely discussed in Salesforce Apex development. There’s no dedicated documentation page or widespread community discussion, making it an underrated yet valuable concept for Apex developers.

In this blog, we’ll explore what marker interfaces are, how Salesforce already uses them behind the scenes, and how you can leverage them in your own Apex applications with a practical, real-world example.

What Is a Marker Interface?

According to Wikipedia, a marker interface is a design pattern used in programming languages that support runtime type information. It allows developers to attach metadata to a class without requiring any implementation.

In simple terms, a marker interface is just an empty interface.

It contains:

  • No methods
  • No properties
  • Nothing to implement

That naturally raises the question:

What’s the purpose of an interface with nothing inside it?

The answer lies in what the interface signals. A marker interface acts as a flag that allows your code or even the Salesforce platform – to recognize certain classes and apply specific behavior at runtime.

How Salesforce Already Uses Marker Interfaces

Marker interfaces are already deeply embedded within the Salesforce platform.

For example, in Aura Components you’ve probably used them many times:

<aura:component implements="force:lightningQuickAction,force:hasRecordId">

Each interface inside the implements attribute is a marker interface.

Although they don’t require any code implementation, they instruct Salesforce to provide additional functionality, such as:

  • Enabling Lightning Quick Actions
  • Providing the current Record Id
  • Changing how the component behaves

Apex also provides built-in marker interfaces.

Examples include:

  • Database.Stateful
  • Database.AllowsCallouts

Neither interface contains methods to implement, yet both significantly change how Apex behaves during execution.

The pattern has been part of Salesforce all along – we simply don’t use it often enough in our own code. 

Creating Your First Marker Interface

The simplest marker interface looks like this:

public interface Trackable {}

Now create a class that implements it:

public class OrderService implements Trackable {}

You can verify the implementation at runtime using the ApexTypeImplementor object.

List<ApexTypeImplementor> results = [
    SELECT Id
    FROM ApexTypeImplementor
    WHERE ClassName = 'OrderService'
    AND InterfaceName = 'Trackable'
    AND IsConcrete = true
];

Assert.areEqual(1, results.size(),
    'OrderService should implement Trackable');

Similarly, another example:

List<ApexTypeImplementor> implementor = [
    SELECT Id
    FROM ApexTypeImplementor
    WHERE ClassName = 'MyConcreteClass'
    AND InterfaceName = 'MyMarkerInterface'
    AND IsConcrete = true
];

Assert.areEqual(
    1,
    implementor.size(),
    'We are able to check if MyConcreteClass implements MyMarkerInterface'
);

Since no System.AssertException is thrown, the marker interface has been successfully implemented.

However, at this stage, it doesn’t provide any practical value.

Let’s look at a real-world use case.

A Real Use Case: Notification Preferences for a Report Engine

Imagine you’re building a report generation framework used by multiple teams.

The framework already handles:

  • Querying data
  • Formatting reports
  • Distributing results

However, different teams have different notification preferences.

Some want:

  • Chatter notifications

Others prefer:

  • Mobile push notifications

Some require both.

Instead of forcing every report class to implement notification methods, marker interfaces provide a clean and scalable solution.

 Step 1 – Create the Core Interface

public interface IReportJob { void execute(Map<String, Object> config); }

Step 2 – Create Notification Marker Interfaces

public interface ChatterNotification {} public interface MobileNotification {}

Step 3 – Let Teams Opt In

A weekly sales report needs both notification types.

public class WeeklySalesReport
implements IReportJob,
           ChatterNotification,
           MobileNotification {

    public void execute(Map<String, Object> config) {
        System.debug('Generating weekly sales summary...');
    }
}

An inventory report only needs Chatter notifications.

public class InventoryCheckReport
implements IReportJob,
           ChatterNotification {

    public void execute(Map<String, Object> config) {
        System.debug('Running inventory check...');
    }
}

Notice that neither class has to implement any notification methods.

Simply implementing the interface is enough.

Step 4 – Let the Framework Handle Notifications

public class ReportRunner {

    public void run(Map<String, Object> config) {

        IReportJob job =
            new ReportFactory().getReport();

        job.execute(config);

        if(job instanceof ChatterNotification){
            System.debug(
                'Posting report completion to Chatter...'
            );
        }

        if(job instanceof MobileNotification){
            System.debug(
                'Sending push notification to mobile...'
            );
        }
    }

    public class ReportFactory {

        public IReportJob getReport() {
            return new WeeklySalesReport();
        }
    }
}

Run the framework:

new ReportRunner().run(new Map<String, Object>());

Output:

DEBUG | Generating weekly sales summary...
DEBUG | Posting report completion to Chatter...
DEBUG | Sending push notification to mobile...

Now switch the factory to return:

InventoryCheckReport

Only the Chatter notification executes – without making any changes to the framework.

Why This Approach Works So Well

The biggest advantage isn’t just simplicity – it’s the clean separation of concerns.

Generic Framework

The ReportRunner doesn’t need to know which report it’s running.

It simply checks which marker interfaces are implemented.

Team Flexibility

Each team decides which notifications they want simply by implementing one or more interfaces.

No additional code is required.

Easy Extensibility

Suppose you later need Slack notifications.

Simply create:

public interface SlackNotification {}

Add one instance of check inside the runner.

Any report can now opt in simply by adding:

implements SlackNotification

No existing report logic changes.

Conclusion

Marker interfaces are a lightweight yet powerful design pattern that can significantly improve the flexibility and maintainability of your Apex applications. By allowing classes to opt into specific behaviors without requiring unnecessary method implementations, they promote cleaner architecture and better separation of concerns.

Whether you’re building reusable frameworks, notification systems, or extensible enterprise applications, marker interfaces provide a scalable alternative to complex inheritance hierarchies. The next time you find yourself relying on multiple boolean flags or lengthy if-else conditions to control behavior, consider whether a marker interface could provide a cleaner and more maintainable solution.

By understanding and applying this underrated Apex design pattern, you can build code that’s easier to extend, simpler to maintain, and better aligned with object-oriented design principles.

By following the above blog instructions, you will be able to learn “How to Use Marker Interfaces in Salesforce Apex (With Practical Examples)“. If you still have queries or any related problems, don’t hesitate to contact us at salesforce@greytrix.com. More details about our integration product are available on our website and Salesforce AppExchange.
We hope you may find this blog resourceful and helpful. However, if you still have concerns and need more help, please contact us at salesforce@greytrix.com.

About Us

Greytrix – a globally recognized and one of the oldest Sage Development Partner and a Salesforce Product development partner offers a wide variety of integration products and services to the end users as well as to the Partners and Sage PSG across the globe. We offer Consultation, Configuration, Training and support services in out-of-the-box functionality as well as customizations to incorporate custom business rules and functionalities that require apex code incorporation into the Salesforce platform.

Greytrix has some unique solutions for Cloud CRM such as Salesforce Sage integration for Sage X3, Sage 100 and Sage 300 (Sage Accpac). We also offer best-in-class Cloud CRM Salesforce customization and development services along with services such as Salesforce Data Migration, Integrated App development, Custom App development and Technical Support business partners and end users. Salesforce Cloud CRM integration offered by Greytrix works with Lightning web components and supports standard opportunity workflow. Greytrix GUMU™ integration for Sage ERP – Salesforce is a 5-star rated app listed on Salesforce AppExchange.
The GUMU™ Cloud framework by Greytrix forms the backbone of cloud integrations that are managed in real-time for processing and execution of application programs at the click of a button.

For more information on our Salesforce products and services, contact us at salesforce@greytrix.com. We will be glad to assist you.

Related Posts