Reputation: 14550
In lombok extension method obj.method()
is a syntax sugar for SomeUtil.method(obj)
. It allows for obj
be null.
Kotlin extensions methods are resolved statically so I assume it's the same syntactic sugar. But when I wrote
fun Any.stringOrNull() = this?.toString()
I got a warning about unnecessary safe call on non-null receiver. Does that mean I can't call extension functions on null objects like with Lombok?
Upvotes: 14
Views: 12792
Reputation: 3801
Be careful, for:
fun Any?.toString(): String
following behavior:
var obj: Any? = null
obj?.toString() // is actually null
obj.toString() // returns "null" string
just spent 15 very frustrating minutes before realized this...
Upvotes: 7
Reputation: 21
val string: String? = "Hello World!" print(string.length)
// Compile error: Can't directly access property of nullable type. print(string?.length)
// Will print the string's length, or "null" if the string is null.
?.
Safe Call operator for nullable receiver##The safe call operator returns null if the value to the left is null, otherwise continues to evaluate the expression to the right, so in order to call any function on nullable receiver you need to use safe call operator after Any.(Use Any?)
Then you can check for null value of this(here this object points to receiver
) inside function body.This is what allows you to call toString() in Kotlin without checking for null: the check happens inside the extension function.
fun Any?.toString(): String { if (this == null) return "null" // after the null check, 'this' is autocast to a non-null type, so the toString() below // resolves to the member function of the Any class return toString() }
Upvotes: 1
Reputation: 81939
You can create extensions on nullable receiver types. In your example, it has to be Any?
instead of Any
which would not allow null, see the docs:
Nullable Receiver
Note that extensions can be defined with a nullable receiver type. Such extensions can be called on an object variable even if its value is
null
, and can check forthis == null
inside the body. This is what allows you to calltoString()
in Kotlin without checking fornull
: the check happens inside the extension function.fun Any?.toString(): String { if (this == null) return "null" // after the null check, 'this' is autocast to a non-null type, so the toString() below // resolves to the member function of the Any class return toString() }
Upvotes: 14
Reputation: 89578
You can call it on a nullable object if you define it to be an extension on a nullable type:
fun Any?.stringOrNull() = ...
Otherwise, like with any other method, you'd have to use the safe call operator.
Upvotes: 19