liveBook · Manning

Internal modifier

As explained in Kotlin in Action, 2E

The internal modifier restricts a Kotlin declaration's visibility to code in the same module.

Use internal when an implementation detail should be available throughout one module but not exposed to external code. A module is a set of Kotlin files compiled together, such as a Gradle source set, Maven project, or IntelliJ IDEA module. section 4.1.3

Keep an implementation type inside the module

internal open class TalkativeButton { private fun yell() = println("Hey!") protected fun whisper() = println("Let's talk!") } fun TalkativeButton.giveSpeech() { // yell() and whisper() are not accessible here } // A public function cannot expose TalkativeButton: // fun useButton(button: TalkativeButton) = ... Here, TalkativeButton is usable by code compiled in the same module, while its private and protected members retain their narrower rules. The public API cannot reference the less-visible internal type. section 4.1.3

Apply internal with these practical boundaries:

  • Use it for module implementation details that should have real encapsulation. section 4.1.3
  • Remember that Gradle test source code can access internal declarations from the main source set. section 4.1.3
  • Do not use packages as a Java-style package-private boundary; Kotlin packages organize namespaces but do not control visibility. section 4.1.3
  • Choose private for a top-level class, function, or property that should be visible only within its declaring file. section 4.1.3
Table 4.2 Kotlin visibility modifiers (view table figure)

Modifier

Class member

Top-level declaration

public (default)

Visible everywhere

Visible everywhere

internal

Visible in a module

Visible in a module

protected

Visible in subclasses

—

private

Visible in a class

Visible in a file

Compare internal with public, protected, and private visibility for class members and top-level declarations. section 4.1.3

Kotlin declarations are public by default, but internal provides a deliberate module boundary for APIs that should not become externally supported. This differs from Java's package-private convention, which can be weakened by code placed in the same package. section 4.1.3 section 4.6

How Kotlin in Action, 2E covers it

How deep it goes
Defines module boundaries, contrasts Java package-private visibility, and demonstrates invalid references from broader APIs.
Examples
Uses TalkativeButton, an internal class whose private and protected members expose illegal access attempts.
What it assumes
Assumes basic Kotlin declarations and distinguishes module, file, class, and package visibility.
What you can do after
Apply internal to hide implementation details while preserving access across a module.
How it connects
Connects internal visibility with public, protected, private, packages, modules, and API encapsulation.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Kotlin in Action, 2E. The section links point to the parts of the book it draws on.