What is the default visibility of a top-level declaration in Kotlin, and how does that compare to Java?
answer
- Kotlin default = public
- Java default = package-private
- Kotlin has NO package-private
- Four modifiers: public/internal/protected/private
- internal ~ closest to package-private but module-wide
basics
~10 sBy default everything in Kotlin is public — visible everywhere. In Java, members with no modifier are package-private (visible only in the same package). Kotlin has no package-private at all.
solid answer
~30 sKotlin's default visibility is `public`: a top-level function, class, or property with no modifier is visible from any module that depends on the file. This contrasts with Java, where omitting a modifier gives **package-private** (default) access, visible only within the same package. Kotlin deliberately drops package-private; its four modifiers are `public`, `internal`, `protected`, and `private`. For top-level declarations only `public`, `internal`, and `private` apply (`protected` is for class members). So the Java habit of relying on "no modifier = package scope" doesn't translate — you must use `internal` (module scope) or `private` (file scope) to restrict a top-level declaration.
go deeper
States that the default is public and that Java's default differs (package-private).
Lists all four modifiers and notes Kotlin removed package-private, with internal as the rough analog.
Explains the module boundary of internal vs Java's package boundary and the API-surface implications of a public default.
Discusses library API governance: explicit-API mode, binary compatibility, and why a public default pushes responsibility onto authors to seal internals.
## Default is public In Kotlin, if you write no visibility modifier, the declaration is **`public`** — accessible from anywhere it can be imported, including other modules. This applies to top-level functions, classes, objects, and properties as well as class members. ```kotlin fun greet() = "hi" // public by default class Service // public by default val VERSION = "1.0" // public by default ``` ## Java contrast Java has **four** access levels: `public`, `protected`, *default (package-private)*, and `private`. The **default** (no keyword) is package-private: visible only inside the same package. Kotlin's default is the opposite end of the spectrum — `public`. ## No package-private in Kotlin Kotlin **removed package-private entirely**. Packages in Kotlin are organizational namespaces, not an access-control boundary. The four Kotlin modifiers are: - `public` (default) — everywhere - `internal` — same **module** (compilation unit) - `protected` — declaring class + subclasses (class members only) - `private` — top-level: same **file**; member: same class `internal` is Kotlin's nearest replacement for Java's package-private, but its boundary is a **module**, not a package, and it's coarser/broader. ## Why this matters in practice A Java developer porting code may expect "no modifier = hidden from other packages." In Kotlin the same declaration is fully public API. To hide it you must explicitly add `internal` or `private`. ```kotlin internal fun helper() {} // visible only inside this module private fun secret() {} // visible only inside this file ``` ## Library design note Because the default is `public`, library authors must be deliberate about what they expose — every unmarked declaration is part of the public API surface and subject to binary/source compatibility concerns.
- What's the closest Kotlin equivalent to Java's package-private, and why isn't it exact?`internal` — but it scopes to the whole module, not a single package, so it's broader. There's no per-package access control in Kotlin.
- Why might a public-by-default language be risky for library authors?Every unmarked declaration is exposed API; you can accidentally publish implementation details and then owe backward compatibility on them. Authors must mark internals explicitly.
Java's no-keyword is a 'staff only' door (your package); Kotlin's no-keyword is a wide-open front door (public).
saying these in an interview costs you the question
- Saying the default is package-private (that's Java)
- Claiming Kotlin has a package-private level
- Thinking the default is `internal`
- Confusing module scope with package scope for `internal`
- Assuming Java access habits transfer unchanged