Use Kotlin’s safe-call operator, `?.`, when a receiver may be null. It combines a null check with a method call or property access: the operation runs for a non-null receiver; otherwise it is skipped and the expression evaluates to `null`. This avoids writing an explicit `if (value != null)` for routine nullable access. section 7.4 section 7.13
Call a method safely
```kotlin fun printAllCaps(str: String?) { val allCaps: String? = str?.uppercase() println(allCaps) } printAllCaps("abc") // ABC printAllCaps(null) // null ``` `uppercase()` still returns `String`, but `str?.uppercase()` has type `String?`: a null receiver can produce null instead of making the call. section 7.4
Safe calls also access nullable properties. They can be chained through an object graph: `person.company?.address?.country` stops at the first null receiver and yields null. This replaces the repeated null checks commonly needed for the same traversal in Java. section 7.4
Listing 7.3 Chaining multiple safe-call operators
class Address(val streetAddress: String, val zipCode: Int,
val city: String, val country: String)
class Company(val name: String, val address: Address?)
class Person(val name: String, val company: Company?)
fun Person.countryName(): String {
val country = this.company?.address?.country #1
return if (country != null) country else "Unknown"
}
fun main() {
val person = Person("Dmitry", null)
println(person.countryName())
// Unknown
}
Follow a chained lookup through nullable `company` and `address`, then handle the nullable country with a fallback. section 7.4
A common pattern is `nullableValue?.let { ... }`. The `let` lambda runs only when the receiver is non-null, so its `it` parameter can be passed to a function requiring a non-nullable argument. Calling `let` directly on a nullable value does not perform that check and still supplies a nullable lambda argument. section 7.8 section 7.10
Send only when an address exists
```kotlin fun sendEmailTo(email: String) { println("Sending email to $email") } var email: String? = "yole@example.com" email?.let { sendEmailTo(it) } email = null email?.let { sendEmailTo(it) } // no call ``` The safe call determines whether `let` executes; inside the lambda, `it` is a non-null `String`. For several nullable values, nested `let` calls can become hard to read, so a regular `if` check may be clearer. section 7.8
The receiver need not be an object property or ordinary method target. A nullable function value has an `invoke` method, so `callback?.invoke()` calls it only when present. Safe calls are one tool among Kotlin’s nullable-value operations: use `?:` for a fallback and reserve `!!` for cases where you deliberately promise a value is non-null. section 10.1.4 section 7.13
Do not assume that `value.method()` proves `value` is non-null. An extension can be declared for a nullable receiver and handle null itself, such as `String?.isNullOrBlank()`. Such an extension is callable without `?.`; when defining extensions, prefer a non-nullable receiver unless handling null is a sensible part of the operation. section 7.10
