ProgrammazioneSviluppatore Android

Come funziona la visibilità (visibility modifiers) in Kotlin: internal, private, protected, public? Quali sono le differenze dei modificatori nei vari contesti - per classi, funzioni, proprietà, oggetti, funzioni di livello superiore e file?

Supera i colloqui con l'assistente IA Hintsage

Risposta

In Kotlin esistono i seguenti modificatori di visibilità:

  • public (predefinito): l'elemento è visibile ovunque.
  • internal: l'elemento è visibile all'interno di un modulo (jar/gradle module ecc.).
  • protected: visibile solo all'interno della classe e delle sue sottoclassi.
  • private: visibile solo all'interno del file o della classe.

Caratteristiche:

  • Per funzioni, proprietà e classi di livello superiore: private limita l'accesso all'ambito del file, internal al modulo, mentre public/protected non ha significato al di fuori della classe.
  • Per i membri di una classe: private è solo all'interno di questa classe, protected più le sottoclassi, internal e public come descritto sopra.
  • All'interno di un oggetto/o di un oggetto companion: analogamente alla classe.
class MyClass { private val secret = "hidden" protected val id = 42 internal fun foo() {} public fun bar() {} } internal fun moduleFunc() {} private fun fileOnlyFunc() {}

Domanda insidiosa

"Una funzione di livello superiore può essere protected? Se sì, come funziona? Se no, perché?"

Risposta: No, una funzione di livello superiore non può essere protected, poiché non esiste una classe a cui appartiene questo livello di accesso. Questo è gestito dal compilatore - verrà generato un errore di compilazione.

protected fun magic() {} // Errore: modificatore protected non consentito per funzioni di livello superiore

Esempi di errori reali a causa della mancanza di conoscenza dei dettagli del tema


Storia

In un'app fintech hanno dimenticato che il modificatore internal consente accesso a tutti gli elementi del modulo. Di conseguenza, durante il refactoring hanno spostato parte della logica in un altro modulo gradle, dopo di che l'accesso ai dati ha smesso di funzionare, ma gli sviluppatori non se ne sono subito accorti, poiché non ci sono stati errori di compilazione nei vecchi test.


Storia

In un progetto multipiattaforma hanno definito dati riservati come proprietà private in un oggetto companion. Si è scoperto che questi dati vengono serializzati e diventano accessibili tramite reflection, poiché erano dichiarati come val senza l'uso di annotazioni che limitano l'esportazione.


Storia

All'avvio di un progetto mobile hanno usato private per le funzioni di livello superiore, ritenendo che questo limitasse l'accesso alle classi partner. Tuttavia, all'interno dello stesso file di utilità, queste funzioni erano visibili a tutti, il che ha portato a una minaccia di fuga di informazioni e a usi imprevisti nella logica aziendale.