{"id":13019,"date":"2026-06-27T09:48:07","date_gmt":"2026-06-27T09:48:07","guid":{"rendered":"https:\/\/www.greytrix.com\/blogs\/salesforce\/?p=13019"},"modified":"2026-06-26T12:21:45","modified_gmt":"2026-06-26T12:21:45","slug":"how-to-use-marker-interfaces-in-salesforce-apex-with-practical-examples","status":"publish","type":"post","link":"https:\/\/www.greytrix.com\/blogs\/salesforce\/2026\/06\/27\/how-to-use-marker-interfaces-in-salesforce-apex-with-practical-examples\/","title":{"rendered":"How to Use Marker Interfaces in Salesforce Apex (With Practical Examples)"},"content":{"rendered":"\n<p>If you&#8217;ve spent time in the Java ecosystem, you&#8217;ve likely come across marker interfaces. Surprisingly, this design pattern is rarely discussed in Salesforce Apex development. There&#8217;s no dedicated documentation page or widespread community discussion, making it an underrated yet valuable concept for Apex developers.<\/p>\n\n\n\n<p>In this blog, we&#8217;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.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-red-color\">What Is a Marker Interface?<\/mark><\/strong><\/h2>\n\n\n\n<p>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.<\/p>\n\n\n\n<p>In simple terms, a marker interface is just an empty interface.<\/p>\n\n\n\n<p>It contains:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>No methods<\/li>\n\n\n\n<li>No properties<\/li>\n\n\n\n<li>Nothing to implement<\/li>\n<\/ul>\n\n\n\n<p>That naturally raises the question:<\/p>\n\n\n\n<p><strong>What&#8217;s the purpose of an interface with nothing inside it?<\/strong><\/p>\n\n\n\n<p>The answer lies in what the interface signals. A marker interface acts as a flag that allows your code or even the Salesforce platform &#8211; to recognize certain classes and apply specific behavior at runtime.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-red-color\">How Salesforce Already Uses Marker Interfaces<\/mark><\/strong><\/h2>\n\n\n\n<p>Marker interfaces are already deeply embedded within the Salesforce platform.<\/p>\n\n\n\n<p>For example, in Aura Components you&#8217;ve probably used them many times:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;aura:component implements=\"force:lightningQuickAction,force:hasRecordId\"&gt;<\/code><\/pre>\n\n\n\n<p>Each interface inside the implements attribute is a marker interface.<\/p>\n\n\n\n<p>Although they don&#8217;t require any code implementation, they instruct Salesforce to provide additional functionality, such as:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Enabling Lightning Quick Actions<\/li>\n\n\n\n<li>Providing the current Record Id<\/li>\n\n\n\n<li>Changing how the component behaves<\/li>\n<\/ul>\n\n\n\n<p>Apex also provides built-in marker interfaces.<\/p>\n\n\n\n<p>Examples include:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Database.Stateful<\/li>\n\n\n\n<li>Database.AllowsCallouts<\/li>\n<\/ul>\n\n\n\n<p>Neither interface contains methods to implement, yet both significantly change how Apex behaves during execution.<\/p>\n\n\n\n<p>The pattern has been part of Salesforce all along &#8211; we simply don&#8217;t use it often enough in our own code.\u00a0<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-red-color\">Creating Your First Marker Interface<\/mark><\/strong><\/h2>\n\n\n\n<p>The simplest marker interface looks like this:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>public interface Trackable {}<\/code><\/pre>\n\n\n\n<p>Now create a class that implements it:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>public class OrderService implements Trackable {}<\/code><\/pre>\n\n\n\n<p>You can verify the implementation at runtime using the <strong>ApexTypeImplementor<\/strong> object.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>List&lt;ApexTypeImplementor&gt; results = &#91;\n    SELECT Id\n    FROM ApexTypeImplementor\n    WHERE ClassName = 'OrderService'\n    AND InterfaceName = 'Trackable'\n    AND IsConcrete = true\n];\n\nAssert.areEqual(1, results.size(),\n    'OrderService should implement Trackable');<\/code><\/pre>\n\n\n\n<p>Similarly, another example:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>List&lt;ApexTypeImplementor&gt; implementor = &#91;\n    SELECT Id\n    FROM ApexTypeImplementor\n    WHERE ClassName = 'MyConcreteClass'\n    AND InterfaceName = 'MyMarkerInterface'\n    AND IsConcrete = true\n];\n\nAssert.areEqual(\n    1,\n    implementor.size(),\n    'We are able to check if MyConcreteClass implements MyMarkerInterface'\n);<\/code><\/pre>\n\n\n\n<p>Since no <strong>System.AssertException<\/strong> is thrown, the marker interface has been successfully implemented.<\/p>\n\n\n\n<p>However, at this stage, it doesn&#8217;t provide any practical value.<\/p>\n\n\n\n<p>Let&#8217;s look at a real-world use case.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-red-color\">A Real Use Case: Notification Preferences for a Report Engine<\/mark><\/strong><\/h2>\n\n\n\n<p>Imagine you&#8217;re building a report generation framework used by multiple teams.<\/p>\n\n\n\n<p>The framework already handles:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Querying data<\/li>\n\n\n\n<li>Formatting reports<\/li>\n\n\n\n<li>Distributing results<\/li>\n<\/ul>\n\n\n\n<p>However, different teams have different notification preferences.<\/p>\n\n\n\n<p>Some want:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Chatter notifications<\/li>\n<\/ul>\n\n\n\n<p>Others prefer:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Mobile push notifications<\/li>\n<\/ul>\n\n\n\n<p>Some require both.<\/p>\n\n\n\n<p>Instead of forcing every report class to implement notification methods, marker interfaces provide a clean and scalable solution.<\/p>\n\n\n\n<p>\u00a0<strong>Step 1 \u2013 Create the Core Interface<\/strong><\/p>\n\n\n\n<p>public interface IReportJob {\n    void execute(Map&lt;String, Object&gt; config);\n}<\/p>\n\n\n\n<p><strong>Step 2 \u2013 Create Notification Marker Interfaces<\/strong><\/p>\n\n\n\n<p>public interface ChatterNotification {}\n\npublic interface MobileNotification {}<\/p>\n\n\n\n<p><strong>Step 3 \u2013 Let Teams Opt In<\/strong><\/p>\n\n\n\n<p>A weekly sales report needs both notification types.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>public class WeeklySalesReport\nimplements IReportJob,\n           ChatterNotification,\n           MobileNotification {\n\n    public void execute(Map&lt;String, Object&gt; config) {\n        System.debug('Generating weekly sales summary...');\n    }\n}<\/code><\/pre>\n\n\n\n<p>An inventory report only needs Chatter notifications.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>public class InventoryCheckReport\nimplements IReportJob,\n           ChatterNotification {\n\n    public void execute(Map&lt;String, Object&gt; config) {\n        System.debug('Running inventory check...');\n    }\n}<\/code><\/pre>\n\n\n\n<p>Notice that neither class has to implement any notification methods.<\/p>\n\n\n\n<p>Simply implementing the interface is enough.<\/p>\n\n\n\n<p><strong>Step 4 \u2013 Let the Framework Handle Notifications<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>public class ReportRunner {\n\n    public void run(Map&lt;String, Object&gt; config) {\n\n        IReportJob job =\n            new ReportFactory().getReport();\n\n        job.execute(config);\n\n        if(job instanceof ChatterNotification){\n            System.debug(\n                'Posting report completion to Chatter...'\n            );\n        }\n\n        if(job instanceof MobileNotification){\n            System.debug(\n                'Sending push notification to mobile...'\n            );\n        }\n    }\n\n    public class ReportFactory {\n\n        public IReportJob getReport() {\n            return new WeeklySalesReport();\n        }\n    }\n}<\/code><\/pre>\n\n\n\n<p>Run the framework:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>new ReportRunner().run(new Map&lt;String, Object&gt;());<\/code><\/pre>\n\n\n\n<p><strong>Output<\/strong>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>DEBUG | Generating weekly sales summary...\nDEBUG | Posting report completion to Chatter...\nDEBUG | Sending push notification to mobile...<\/code><\/pre>\n\n\n\n<p>Now switch the factory to return:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>InventoryCheckReport<\/code><\/pre>\n\n\n\n<p>Only the Chatter notification executes &#8211; without making any changes to the framework.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-red-color\">Why This Approach Works So Well<\/mark><\/strong><\/h2>\n\n\n\n<p>The biggest advantage isn&#8217;t just simplicity &#8211; it&#8217;s the clean separation of concerns.<\/p>\n\n\n\n<p><strong>Generic Framework<\/strong><\/p>\n\n\n\n<p>The <code>ReportRunner<\/code> doesn&#8217;t need to know which report it&#8217;s running.<\/p>\n\n\n\n<p>It simply checks which marker interfaces are implemented.<\/p>\n\n\n\n<p><strong>Team Flexibility<\/strong><\/p>\n\n\n\n<p>Each team decides which notifications they want simply by implementing one or more interfaces.<\/p>\n\n\n\n<p>No additional code is required.<\/p>\n\n\n\n<p><strong>Easy Extensibility<\/strong><\/p>\n\n\n\n<p>Suppose you later need Slack notifications.<\/p>\n\n\n\n<p>Simply create:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>public interface SlackNotification {}<\/code><\/pre>\n\n\n\n<p>Add one instance of check inside the runner.<\/p>\n\n\n\n<p>Any report can now opt in simply by adding:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>implements SlackNotification<\/code><\/pre>\n\n\n\n<p>No existing report logic changes.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-red-color\">Conclusion<\/mark><\/strong><\/h2>\n\n\n\n<p>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.<\/p>\n\n\n\n<p>Whether you&#8217;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.<\/p>\n\n\n\n<p>By understanding and applying this underrated Apex design pattern, you can build code that&#8217;s easier to extend, simpler to maintain, and better aligned with object-oriented design principles.<\/p>\n\n\n\n<p>By following the above blog instructions, you will be able to learn \u201c<strong>How to Use Marker Interfaces in Salesforce Apex (With Practical Examples)<\/strong>\u201c. If you still have queries or any related problems, don\u2019t hesitate to contact us at <a href=\"mailto:salesforce@greytrix.com\" target=\"_blank\" rel=\"noreferrer noopener\">salesforce@greytrix.com<\/a>. More details about our integration product are available on <a href=\"https:\/\/www.greytrix.com\/salesforce-cloud-services\/\" target=\"_blank\" rel=\"noreferrer noopener\">our website<\/a> and <a href=\"https:\/\/appexchange.salesforce.com\/appxListingDetail?listingId=a0N30000000psM5EAI\" target=\"_blank\" rel=\"noreferrer noopener\">Salesforce AppExchange<\/a>.<br>We hope you may find this blog resourceful and helpful. However, if you still have concerns and need more help, please contact us at <a href=\"mailto:salesforce@greytrix.com\" target=\"_blank\" rel=\"noreferrer noopener\">salesforce@greytrix.com<\/a>.<\/p>\n\n\n\n<p style=\"text-align: justify\"><b>About Us<\/b><\/br>\n<p><a href=\"https:\/\/www.greytrix.com\/\">Greytrix<\/a> \u2013 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.<br><br> Greytrix has some unique solutions for Cloud CRM such as <a href=\"\">Salesforce Sage integration<\/a> for <a href=\"https:\/\/www.greytrix.com\/sage-x3-erp\/integration\/\">Sage X3<\/a>, <a href=\"https:\/\/www.greytrix.com\/salesforce-cloud-services\/sage-100-integration\/\">Sage 100<\/a> and <a href=\"https:\/\/www.greytrix.com\/salesforce-cloud-services\/sage-300-integration\/\">Sage 300 (Sage Accpac)<\/a>. We also offer best-in-class Cloud CRM <a href=\"https:\/\/www.greytrix.com\/salesforce-cloud-services\/crm-development\/\">Salesforce customization and development services<\/a> along with services such as Salesforce <a href=\"https:\/\/www.greytrix.com\/salesforce-cloud-services\/data-migration-support\/\">Data Migration<\/a>, <a href=\"https:\/\/www.greytrix.com\/salesforce-cloud-services\/crm-development\/\">Integrated App development<\/a>, 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&#x2122; integration for Sage ERP \u2013 Salesforce is a 5-star rated app listed on <a href=\"https:\/\/appexchange.salesforce.com\/appxListingDetail?listingId=a0N30000000psM5EAI\" target=\"_blank\" rel=\"noopener\">Salesforce AppExchange<\/a>.<br> The GUMU&#x2122; 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.<br><br> For more information on our Salesforce products and services, contact us at <a href=\"mailto:salesforce@greytrix.com\">salesforce@greytrix.com<\/a>. We will be glad to assist you.<\/p>\n\n\n\n<p><strong>Related Posts<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/www.greytrix.com\/blogs\/salesforce\/2026\/01\/29\/sibling-to-sibling-communication-in-lwc-using-a-common-parent-a-complete-guide-part-3\/\" target=\"_blank\" rel=\"noreferrer noopener\">Sibling-to-Sibling Communication in LWC Using a Common Parent \u2013 A Complete Guide (Part 3)<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/www.greytrix.com\/blogs\/salesforce\/2026\/03\/25\/yyyy-vs-yyyy-in-salesforce-apex-understanding-the-critical-date-formatting-difference\/\" target=\"_blank\" rel=\"noreferrer noopener\">YYYY vs yyyy in Salesforce Apex: Understanding the Critical Date Formatting Difference<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/www.greytrix.com\/blogs\/salesforce\/2026\/03\/23\/polymorphic-apex-in-salesforce-how-to-write-flexible-code-for-multiple-objects\/\" target=\"_blank\" rel=\"noreferrer noopener\">Polymorphic Apex in Salesforce: How to Write Flexible Code for Multiple Objects<\/a><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>If you&#8217;ve spent time in the Java ecosystem, you&#8217;ve likely come across marker interfaces. Surprisingly, this design pattern is rarely discussed in Salesforce Apex development. There&#8217;s no dedicated documentation page or widespread community discussion, making it an underrated yet valuable concept for Apex developers. In this blog, we&#8217;ll explore what marker interfaces are, how Salesforce\u2026 <span class=\"read-more\"><a href=\"https:\/\/www.greytrix.com\/blogs\/salesforce\/2026\/06\/27\/how-to-use-marker-interfaces-in-salesforce-apex-with-practical-examples\/\">Read More &raquo;<\/a><\/span><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3],"tags":[3481,3470,3460,3484,3480,3456,3453,3468,3483,3476,3475,3463,3471,3461,3459,3458,3455,3473,3469,3464,3452,3457,3472,3465,3450,3466,3477,3487,3485,3462,3486,3451,2463,3488,2782,3478,2703,3474,3479,3482,3454,3467],"class_list":["post-13019","post","type-post","status-publish","format-standard","hentry","category-salesforce-srv","tag-apex-architecture-patterns","tag-apex-batch-class-patterns","tag-apex-class-behavior-modification","tag-apex-developer-guide","tag-apex-framework-design","tag-apex-interface-implementation","tag-apex-marker-interface-pattern","tag-apex-notification-design-pattern-using-interfaces","tag-apex-polymorphism-2","tag-apex-polymorphism","tag-apex-polymorphism-marker-interfaces-in-apex","tag-apextypeimplementor-query","tag-aura-component-implements-attribute","tag-composition-over-inheritance-apex","tag-database-allowscallouts","tag-database-stateful-apex","tag-empty-interface-apex","tag-forcelightningquickaction-interface","tag-how-to-add-opt-in-behavior-in-apex-classes","tag-how-to-implement-marker-interfaces-in-salesforce-apex","tag-instanceof-keyword-apex","tag-ireportjob-apex","tag-lwc-component-behavior","tag-marker-interface-pattern-for-apex-developers","tag-marker-interfaces-in-apex","tag-multiple-interfaces-apex","tag-multiple-interfaces-in-apex","tag-reusable-apex-frameworks","tag-runtime-interface-detection-apex","tag-runtime-type-information-apex","tag-salesforce-advanced-apex","tag-salesforce-apex-design-patterns","tag-salesforce-coding-standards","tag-salesforce-developer-tips-2","tag-salesforce-development-best-practices","tag-salesforce-enterprise-architecture","tag-salesforce-isv-development","tag-salesforce-managed-package-development","tag-salesforce-notification-framework","tag-salesforce-object-oriented-programming","tag-tagging-interfaces-apex","tag-using-instanceof-with-interfaces-in-apex"],"_links":{"self":[{"href":"https:\/\/www.greytrix.com\/blogs\/salesforce\/wp-json\/wp\/v2\/posts\/13019","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.greytrix.com\/blogs\/salesforce\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.greytrix.com\/blogs\/salesforce\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.greytrix.com\/blogs\/salesforce\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.greytrix.com\/blogs\/salesforce\/wp-json\/wp\/v2\/comments?post=13019"}],"version-history":[{"count":14,"href":"https:\/\/www.greytrix.com\/blogs\/salesforce\/wp-json\/wp\/v2\/posts\/13019\/revisions"}],"predecessor-version":[{"id":13033,"href":"https:\/\/www.greytrix.com\/blogs\/salesforce\/wp-json\/wp\/v2\/posts\/13019\/revisions\/13033"}],"wp:attachment":[{"href":"https:\/\/www.greytrix.com\/blogs\/salesforce\/wp-json\/wp\/v2\/media?parent=13019"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.greytrix.com\/blogs\/salesforce\/wp-json\/wp\/v2\/categories?post=13019"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.greytrix.com\/blogs\/salesforce\/wp-json\/wp\/v2\/tags?post=13019"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}