Implicit Public Visibility of Apex Classes and Methods Without Explicit Access Modifiers
0 reputation · 10 Feb 2023, 16:30 UTC
0 reputation · 10 Feb 2023, 16:30 UTC
In Apex, any top‑level class declared without an explicit access modifier is implicitly public, and methods inside such a class also default to public. This default visibility can unintentionally expose internal implementation details to other code, creating security and maintenance risks.
Developers must verify that the intended access level matches the design, yet the language provides no compile‑time warning for accidental public exposure. The challenge is to establish a reliable method for auditing and enforcing visibility declarations across projects.
What is the recommended approach to enforce private visibility for internal utility classes in Apex?
Can a static analysis rule be defined to flag missing access modifiers on all top‑level classes and methods?
Is there a configuration or tool that treats default visibility as a compilation error?
The Apex compiler provides no mechanism to treat implicit public visibility as a compilation error. The recommended approach combines explicit coding standards with static analysis tooling.
\n\nApex’s default-public behavior is by design for the platform’s multi-tenant architecture, but it means any top-level class or method lacking private, protected, or public is publicly accessible by default.
private to all internal utility classes and methods.MissingAccessModifier to error.sfdx force:apex:lint --format json --ruleset .vscode/apex-ruleset.json as part of your pipeline to verify enforcement.If you have existing classes without modifiers, retroactive addition of private may impact dependent code. Verify API usage patterns before applying modifiers globally.
Use comments to ask for clarification. Post a solution as an answer.
35,275 reputation · 10 Feb 2023, 17:59 UTC
One clarification worth adding: in Apex, an omitted access modifier makes a top-level class implicitly public, but methods and fields inside it still default to private unless explicitly marked public or global. The class boundary is open, yet individual members remain inaccessible from other classes by default.
Practical verification: create a modifier-less class and a modifier-less method, then call that method from a separate class in the same org. The compiler should reject the call; if it does not, treat that as version-specific behavior to confirm against your target API version before relying on it.