В Kotlin модификаторы видимости позволяют контролировать доступ к объявлениям: классам, свойствам, функциям и топ-левел (на уровне файла) сущностям. В отличие от Java, где модификаторы действуют только на уровне класса, в Kotlin они работают и для top-level объявлений, что важно для структурирования больших проектов и library API.
В Java нет модификаторов видимости для функций или свойств вне класса — всё находится внутри public (или package-private) класса. В Kotlin принято структурировать проект по своему, часто функция или свойство находятся не внутри класса, а прямо в файле.
Часто разработчики Java ожидают, что public по умолчанию работает так же, как в Java, но в Kotlin top-level function (или свойство) видно во всех модулях, если не помечено иначе. Некорректное определение видимости может привести к лексическому засорению публичного API, неожиданной доступности внутренних утилит, либо к недоступности нужных публичных функций.
В Kotlin доступны следующие модификаторы:
Пример:
// file: Foo.kt private fun utilityFun() {} internal val bar: Int = 10 public val baz: Int = 20 // public не обязателен fun printValue() { println(bar) }
Можно ли использовать protected для top-level функции?
Нет, protected релевантен только членам класса/интерфейса, top-level такие элементы не поддерживают.
Если объявить top-level функцию с internal, будет ли она видна внутри других модулей?
Нет. Она будет видна только в пределах текущего jar/Gradle-модуля.
Чем отличается private class от private top-level function?
Пример:
// file: Utils.kt private fun helper() { /* ... */ } // виден только в этом файле internal fun useful() { /* ... */ } // виден во всём модуле
Тестовые утилиты объявлены public и так попадают в artefact, мешая клиенту библиотеки — становится видно всё, что не относится к public API.
Плюсы:
Минусы:
Внутренние функции объявлены private, утилиты с internal видимостью для общего использования внутри модуля, только тщательно продуманные интерфейсы имеют public-доступ.
Плюсы:
Минусы: