← Назад к вопросам

Что такое тип с вопросительным знаком?

1.6 Junior🔥 261 комментариев
#Kotlin основы

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI6 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Тип с вопросительным знаком (Nullable Type) в Kotlin

В Kotlin тип с вопросительным знаком (например, String?, Int?, User?) обозначает nullable-тип — специальный тип, который может хранить либо значение указанного типа, либо null. Это фундаментальная особенность системы типов Kotlin, направленная на устранение проблемы NullPointerException (NPE) на уровне компилятора.

Основная концепция

В отличие от Java, где любая ссылка на объект может быть null, Kotlin по умолчанию разделяет типы на:

  • NonNull-типы — гарантированно не содержат null (например, String, Int)
  • Nullable-типы — явно помечаются вопросительным знаком и могут содержать null
// Non-null тип - не может содержать null
val name: String = "Алексей" // OK
// val name2: String = null // ОШИБКА компиляции!

// Nullable тип - может содержать null
val nullableName: String? = "Алексей" // OK
val nullableName2: String? = null // OK

Почему это важно?

  1. Безопасность на уровне компиляции — компилятор Kotlin отслеживает возможные NPE и заставляет разработчика явно обрабатывать случаи с null

  2. Явность намерений — код становится самодокументируемым: видно, где ожидается возможное отсутствие значения

  3. Сокращение проверок — хотя проверки всё ещё нужны, они становятся более структурированными и менее многословными

Работа с nullable-типами

Kotlin предоставляет несколько механизмов для безопасной работы с nullable. .

1. Безопасный вызов (Safe Call Operator) ?.

val user: User? = getUser()
val length: Int? = user?.name?.length // Если user или name = null, вернёт null

2. Элвис-оператор (Elvis Operator) ?:

val name: String = user?.name ?: "Гость" // Если name = null, использует "Гость"
val length: Int = user?.name?.length ?: 0

3. Оператор утверждения non-null !!

val name: String = user!!.name // Генерирует NPE если user = null
// Использовать с осторожностью, только когда уверены в non-null значении

4. Умное приведение типов (Smart Cast)

fun processUser(user: User?) {
    if (user != null) {
        // Компилятор автоматически "кастует" user к типу User (не User?)
        val name: String = user.name // Безопасно!
    }
}

5. Безопасное приведение типов as?

val anyValue: Any? = "Текст"
val stringValue: String? = anyValue as? String // Если приведение невозможно, вернёт null

Практический пример

data class Address(val street: String?, val city: String)
data class User(val name: String, val address: Address?)

fun getUserCity(user: User?): String {
    // Цепочка безопасных вызовов с элвис—оператором
    return user?.address?.city ?: "Неизвестный город"
}

fun main() {
    val user1 = User("Иван", Address(null, "Москва"))
    val user2 = User("Пётр", null)
    val user3: User? = null
    
    println(getUserCity(user1)) // Москва
    println(getUserCity(user2)) // Неизвестный город
    println(getUserCity(user3)) // Неизвестный город
}

Отличия от Java

  1. В Kotlin система типов разделена явно, в Java все объектные типы неявно nullable
  2. Kotlin требует явной обработки возможных null-значений
  3. Примитивные типы в Kotlin (Int, Double и т.д.) также могут быть nullable через Int?, что соответствует Java—обёрткам типа Integer

Важные нюансы

  • Nullable-типы несовместимы с non-null типами без явного преобразования
  • Generic-типы также могут быть nullable: List<String?>, List<User>?, List<User?>?
  • Platform-типы при взаимодействии с Java кодом — особый случай, требующий внимания

Заключение

Типы с вопросительным знаком в Kotlin — это не просто синтаксический сахар, а фундаментальный механизм безопасности, который перемещает обработку ошибок, связанных с null, со времени выполнения на время компиляции. Это заставляет разработчиков явно думать о случаях отсутствия значений и писать более надёжный код, что особенно важно в Android—разработке, где NPE традиционно были одной из самых частых причин падения приложений.

Что такое тип с вопросительным знаком? | PrepBro