History of the question:
Visibility modifiers are a key feature of Kotlin, inherited and improved compared to Java. They allow you to restrict access to classes, functions, and properties, supporting better practices of encapsulation and modularity.
Problem:
Incorrect use of visibility can lead to violations of architectural layers, leakage of implementation outward, or vice versa — making classes and methods inaccessible where they are needed. Errors in this are often discovered too late.
Solution:
Kotlin has four visibility modifiers:
public — accessible everywhere (default)internal — accessible only within a single moduleprotected — accessible within a class and its subclassesprivate — accessible only within a file, class, or objectCode example:
open class Base { private fun onlyBase() {} protected fun baseAndDerived() {} internal fun insideModule() {} public fun anyone() {} } class Derived : Base() { fun test() { baseAndDerived() // accessible // onlyBase() — error } }
Key features:
internal is specific to Kotlin, absent in Javaprivate restricts visibility by fileHow does the internal modifier work when publishing a library?
internal hides elements within a single module, but if you compile the library into a jar/aar, internal elements are visible through reflection.
What is the difference between private for a class property and a top-level function?
private on a class property restricts visibility to the class itself, while for top-level, it restricts visibility to the file where the element is declared.
Can you apply protected to a top-level function?
No, protected is only allowed for members of a class or interface. It cannot be used for top-level — there will be a compilation error.
A large library declared almost all APIs as public, including utilities and helpers — as a result, users became dependent on implementation details.
Pros:
Cons:
Only necessary classes declared as public, others internal or private, visibility levels distinctly separated.
Pros:
Cons: