Apex Access Specifiers
- Access specifiers in Apex define who can access a class, method, or variable. They determine the scope and visibility of the code elements.
- Each class can have it’s own access specifiers. Apex supports the following access specifiers:
- private:
- Scope: Accessible only within the same class in which it is defined. These can’t be Accessible from outside the class.
- Default Modifier: If no access specifier is defined, the member is treated as private by default.
Note: Private access specifiers can be applicable for “Class Members” and “Test Classes”.
- Use Case: When the data or method should not be exposed outside the class.
✅ Example:
public class MyClass {
private Integer counter = 0;
private void incrementCounter() {
counter++;
}
}
- protected:
- Scope: Accessible within the class and its inner classes or subclasses (only when used in inheritance).
- Not available for top-level classes (i.e., classes defined in their own file).
Note: We can’t access them from other Independent Classes inside the Organization.
✅ Example:
public class ParentClass {
protected String protectedMessage = ‘Hello from Parent!’;
}
public class ChildClass extends ParentClass {
public void showMessage() {
System.debug(protectedMessage); // Accessible here
}
}
- public:
- Scope: Accessible within the same namespace, which generally means within the same Salesforce org (among Apex code).
Note: Public access specifiers can be applicable for both “Classes and it’s Member”.
- Use Case: Use when you want methods or variables to be available across different classes in the org but not outside it, like in a managed package.
✅ Example:
public class Utility {
public static void showInfo() {
System.debug(‘Public method called’);
}
}
- global:
- Scope: Accessible across all namespaces, even in other managed packages or external orgs.
- Note: All the Batch Classes, Schedule Classes, Webservices, and API’s should be defined as “Global”.
- Note: Each Business Logic Class should be defined with either “Public/Global” access specifier.
- Use Case: Use this only when absolutely necessary, especially for code in managed packages that must be exposed publicly.
- Best Practice: Avoid using global unless it’s critical for interoperability.
✅ Example:
global class GlobalAPI {
global static void callExternal() {
System.debug(‘Global access method’);
}
}
🔁 Comparison Table:
Access Modifier | Scope | Typical Use Case |
private | Same class only | Internal helper methods or variables |
protected | Same class + inner/subclasses | Inherited logic |
public | Any class in same namespace/org | Shared logic within org |
global | Any class in any org or package | API-level exposure or managed packages |
💡 Best Practices:
- Use private by default to limit exposure.
- Use public only when sharing within your org is necessary.
- Use global only for APIs or shared package components.
- Avoid overexposing your code; tighter visibility = better control and security.