ProgrammierungAndroid Entwickler

Wie funktionieren Sichtbarkeitsmodifikatoren (visibility modifiers) in Kotlin: internal, private, protected, public? Wie unterscheiden sich die Modifikatoren in verschiedenen Kontexten – für Klassen, Funktionen, Eigenschaften, Objekte, top-level Funktionen und Dateien?

Bestehen Sie Vorstellungsgespräche mit dem Hintsage-KI-Assistenten

Antwort

In Kotlin gibt es folgende Sichtbarkeitsmodifikatoren:

  • public (standardmäßig): Das Element ist überall sichtbar.
  • internal: Das Element ist nur innerhalb eines Moduls (Jar/Gradle-Modul usw.) sichtbar.
  • protected: Sichtbar nur innerhalb der Klasse und deren Unterklassen.
  • private: Sichtbar nur innerhalb der Datei oder Klasse.

Besonderheiten:

  • Für top-level Funktionen, Eigenschaften und Klassen: private schränkt den Zugriff auf den Dateirahmen ein, internal auf das Modul, und public/protected hat außerhalb der Klasse keinen Sinn.
  • Für Klassenmitglieder: private ist nur innerhalb dieser Klasse, protected umfasst zusätzlich die Unterklassen, internal und public wie oben beschrieben.
  • Innerhalb eines Objekts/Companion-Objekts: ähnlich wie bei der Klasse.
class MyClass { private val secret = "hidden" protected val id = 42 internal fun foo() {} public fun bar() {} } internal fun moduleFunc() {} private fun fileOnlyFunc() {}

Fangfrage

"Kann eine top-level Funktion protected sein? Wenn ja – wie funktioniert das? Wenn nein – warum?"

Antwort: Nein, eine top-level Funktion kann nicht protected sein, da es keine Klasse gibt, zu der diese Zugriffsart gehört. Der Compiler ist dafür verantwortlich – es tritt ein Kompilierungsfehler auf.

protected fun magic() {} // Fehler: Der Modifikator protected ist für top-level Funktionen nicht erlaubt

Beispiele für reale Fehler aufgrund mangelnden Wissens über die Feinheiten des Themas


Geschichte

In einer Fintech-Anwendung wurde vergessen, dass der internal-Modifikator Zugriff auf alle Elemente des Moduls gewährt. Dadurch wurde bei der Refaktorisierung ein Teil der Logik in ein anderes Gradle-Modul verschoben, was den Zugriff auf Daten verhinderte. Die Entwickler bemerkten dies jedoch nicht sofort, da es während der Kompilierung keine Fehler in den alten Tests gab.


Geschichte

In einem Multiplattformprojekt wurden vertrauliche Daten als private Eigenschaften im Companion-Objekt definiert. Es stellte sich heraus, dass diese Daten serialisiert wurden und über Reflection zugänglich waren, da sie als val ohne Verwendung von Annotationen deklariert wurden, die den Export beschränken.


Geschichte

Zu Beginn eines mobilen Projekts wurde private für top-level Funktionen verwendet, in der Annahme, dass dies den Zugriff von Partnerklassen einschränken würde. Innerhalb einer gemeinsamen Datei mit Utils waren diese Funktionen jedoch für alle sichtbar, was zu einem Risiko des Informationslecks und zu unvorhergesehenem Einsatz in der Geschäftlogik führte.