1

I have this code in Kotlin in android studio:

result.put(REGISTER_DATE, if (activityData.registerDate == null) -1 else activityData.registerDate.totalDays)

As you can see I check registerDate is not null, but I have to put non-null assert after activityData.registerDate to eliminate null error:

result.put(REGISTER_DATE, if (activityData.registerDate == null) -1 else activityData.registerDate!!.totalDays)

Is this a bug in Kotlin or is related to Android Studio?

mohammad
  • 1,248
  • 3
  • 15
  • 27
  • You shouldn't nest if else statements in function calls like that. Use elvis operator or extract the condition to a variable, for readability – Tim Feb 26 '18 at 14:04

3 Answers3

6

Is this a bug in Kotlin or is related to Android Studio?

It is neither. activity.registerDate is a mutable nullable property of an object and as such it can (theoretically) be changed at any time, by another thread. The Kotlin compiler doesn't have enough knowledge to prove as an undisputable truth that the property's value won't change when you load it for the second time.

The typical way to avoid this is to load the property just once, capturing it in a local variable. In the particular case you're showing, all you need is the Elvis operator:

activityData.registerDate?.totalDays ?: -1
Marko Topolnik
  • 195,646
  • 29
  • 319
  • 436
3

This isn't a bug, smart casting does not work in such a situation. You can make use of the Elvis Operator to fix the code to a better solution:

result.put(REGISTER_DATE, activityData.registerDate?.totalDays ?: -1)

The expression activityData.registerDate?.totalDays either evaluates to the value of totalDays or null in case any of the values accessed in the safe-operator chain also is null. If the expression evaluates to null the Elvis Operator will take care of providing your default value -1.

s1m0nw1
  • 76,759
  • 17
  • 167
  • 196
3

Probably you are checking mutable property (var). And due to possible concurrency issues Kotlin compiler doesn't perform smart cast to non-null value.

By the way, there is another Kotlin way to do such checks:

 result.put(REGISTER_DATE, activityData.registerDate?.totalDays ?: -1)
hluhovskyi
  • 9,556
  • 5
  • 30
  • 42