Under Explicit API strict mode, which declarations get flagged and which are exempt? Give concrete examples.
answer
- Only public + protected are checked
- Two triggers: no visibility keyword, inferred return type
- Exempt: private, internal, local, overrides
- Constructor val/var needs explicit visibility
- Override signature is inherited, so untouched
basics
~10 sIt flags things visible outside your module — public and protected members that don't say their visibility, and public functions/properties with no written return type. Private, internal, local code, and overrides are left alone.
solid answer
~40 sStrict mode scrutinizes only the API surface: public and protected declarations. It raises an error when such a declaration lacks an explicit visibility modifier (relying on the implicit public default), and when a public/protected function or property body relies on an inferred return type rather than a declared one. Exempt: private and internal declarations (not part of the API), local declarations inside function bodies, and overrides — an override inherits the supertype's signature, so its return type is already fixed and need not be repeated. Property accessors and primary-constructor val/var parameters follow the same rule as the property they back. Constant or trivially-typed cases still require the annotation in strict mode if they are public. The net effect: every symbol a consumer can see carries a deliberate visibility keyword and a spelled-out type.
code
kotlin · 9 lines// FLAGGED (public default + inferred type)
fun size(s: String) = s.length
// FIXED
public fun size(s: String): Int = s.length
// EXEMPT
private fun guard() {}
override fun toString() = "x" // inherited signaturego deeper
Knows public stuff is checked and private/internal is left alone.
Lists both triggers (visibility + return type) and the exemptions including overrides and locals.
Explains why overrides and internal are exempt in terms of API surface, and handles constructor properties.
Reasons about how the rule set keeps signal high and noise low across a large public API, and how it interacts with KMP/expect-actual surfaces.
## The mental model Explicit API mode only cares about what **leaves your module** — i.e., your **API surface**. That means **`public`** and **`protected`** declarations. Everything that is invisible to consumers is exempt. ## Flagged in strict mode 1. **Missing explicit visibility on a public/protected member** — relying on the implicit `public` default. 2. **Inferred return type on a public/protected function or property** — no declared type. ```kotlin // FLAGGED: no visibility keyword (defaults to public) and inferred return type fun total(items: List<Int>) = items.sum() // OK public fun total(items: List<Int>): Int = items.sum() ``` ## Exempt - **`private` and `internal`** declarations — not part of the public API at all. - **Local declarations** (functions/vals declared inside a function body). - **Overrides** — `override fun foo(): Int` inherits its signature from the supertype, so the type is already pinned; you don't have to restate visibility/type purely to satisfy the mode. - Property **getters/setters** are governed by the property's own visibility. ```kotlin class Cache { private fun evict() {} // exempt: private internal fun warmUp(): Unit {} // exempt: internal fun load(): String { // FLAGGED: missing 'public' keyword on a public member fun normalize() = "x" // exempt: local return normalize() } } interface Loader { fun load(): String } class FileLoader : Loader { override fun load() = "file" // exempt: override (signature inherited) } ``` ## Constructor properties A `val`/`var` in a **primary constructor** is a public property by default, so in strict mode it must carry an explicit visibility: ```kotlin class User(public val id: Long, internal val token: String) ``` ## Why these exemptions make sense The whole point is curating the **consumer-visible** surface. `private`/`internal` aren't visible, locals don't escape, and overrides have a signature dictated by the supertype — flagging any of those would be noise without protecting the API.
- Why are overrides exempt from the return-type requirement?An override's signature is fixed by the supertype, so the type is already explicit and stable; restating it adds nothing.
- Is a primary-constructor `val id: Long` flagged?Yes if it's effectively public — you must write the visibility explicitly, e.g. public val id: Long, or make it internal/private.
saying these in an interview costs you the question
- Claiming private declarations get flagged
- Thinking overrides must restate their return type to satisfy the mode
- Saying it checks function parameters' types (those are always explicit anyway)
- Believing internal members count as API surface
- Not realizing constructor val/var are public properties