Почему "Умный бросок на kotlin.String" в IntelliJ
Я написал свой класс с аргументом NULL
class MyClass(a: String? = null) {
var b: String
init {
if( a == null ) {
b = "N/A"
}
else {
b = a
}
}
}
и заметил, что IntelliJ предупреждает о b = a
назначение
Smart cast to kotlin.String
Почему это предупреждение и как его избежать?
2 ответа
Это не предупреждение, просто информация о том, что компилятор знает вашу переменную a
быть не null
, В результате его можно использовать как String
вместо обнуляемого String?
и, следовательно, без безопасного оператора, например
В противном случае вам нужно явно привести a: String?
в String
чтобы сделать его присваиваемым String
переменная b
, как показано на следующем скриншоте:
Это не то, чего следует избегать, это языковая функция, называемая умным составом.
Компилятор обнаружил, что a
является ненулевым значением в заданном пути кода, и поэтому оно доступно для вас с ненулевым значением String
тип, который позволяет вам использовать его напрямую, не беспокоясь о его обнуляемости. Если вы не получили умный актерский состав, вам пришлось бы вручную кастовать его из String?
к String
вызывать методы для него - или назначать его ненулевой переменной, как в вашем случае.
Другой, возможно, более простой пример, чтобы понять, когда умный бросок вступает в силу, с подклассами. Допустим, у вас есть Person
а также Customer
классы, причем только последний, имеющий getPurchases()
метод.
В Java для вызова указанного метода вам нужно будет сделать следующее:
if (p instanceof Customer) {
((Customer)p).getPurchases();
}
В Kotlin вы получаете умный бросок внутри if
блок для подтипа, для которого вы уже сделали проверку:
if (p is Customer) {
p.getPurchases()
}
Если вы думаете об этом, актерский состав из String?
в String
работает тот же механизм - вы получаете умный бросок и к более конкретному типу.
if (a != null)
учитывая a
типа String?
в основном так же, как
if (a is String)