Нет исключения NullPointerException при вызове функции расширения по нулевой ссылке

#kotlin #null

#kotlin #null

Вопрос:

Я немного озадачен тем, почему в этом коде нигде нет NullPointerException выброшенных:

 fun main() {
   null.print()
}

fun <T> T.print() {
    this.let { println(it) }
}
  

Нет ни предупреждения компилятора, ни исключения при вызове функции расширения print над null значением, поскольку оно определено с ненулевым типом получателя, и снова нет исключения при вызове let по этой null ссылке, хотя let также имеет ненулевой тип получателя. В чем причина?

Комментарии:

1. «определено с ненулевым типом получателя», нет, <T> совпадает с <T : Any?> , поэтому получатель может быть нулевым

Ответ №1:

Для методов расширения kotlin предоставляет синтаксический сахар. Когда вы вызываете метод расширения, kotlin здесь предоставляет оболочку сверху; так что, используя это, вы можете получить экземпляр вызывающего объекта. Поэтому, когда вы вызываете null.print() , это в основном вызов print(null) снизу.

Итак, вы можете подумать о следующей функции

 fun <T> T.print()
  

преобразовано в

 fun <T> print(T t)
  

То же самое касается let , это метод расширения, который фактически передает null параметр let вместо вызова let на null экземпляре.

Пожалуйста, обратите внимание, что я новичок в kotlin, поэтому буду признателен за любое исправление.