Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Kotlin Extension Any?.toString()

I have been trying to use extension functions in Kotlin.

class ExtensionExample() {

   var name: String? = null

   fun Any?.toString() : String {

       if (this == null) {
           return "Value is null"
       }

       return "Value is not null"
   }
}

When I print the name variable like below

println(ExtensionExample().name.toString())

It should print like

Value is null

But it doesn't print like I expected. It only prints null.

Can someone explain please?

like image 817
Zumry Mohamed Avatar asked Nov 07 '25 09:11

Zumry Mohamed


1 Answers

Extension functions have scopes. This is why it is not accessible outside of the ExtensionExample class.

Usually, extension functions are defined as top-level functions. That is, they tend to belong outside of a class.

Your toString extension is defined within ExtensionExample. This is possible, but it means it is only available in the scope of this class, and this class only.

Your main method is likely a top-level function (and not a member of that class), so it doesn't have access to this extension function.

Only other members can access this extension function:

class ExtensionExample {

    var name: String? = null

    fun Any?.toString(): String {
        return if (this == null) "Value is null" else "Value is not null"
    }

    fun foo() {
        println(name.toString())
    }

}

fun main(args: Array<String>) {
    ExtensionExample().foo()
}

prints "Value is null"

Try it online!

The reason why it compiles is that the toString method that is being called is the Any?.toString method from the kotlin-stdlib. That is, this method already exists.

fun Any?.toString(): String

Returns a string representation of the object. Can be called with a null receiver, in which case it returns the string "null".

Move your extension function out of the class. Your extension function will then hide the stdlib's extension, and any invocation in the same package not explicitly importing kotlin.toString will use your function.

Here is a working version of your code:

class ExtensionExample {

    var name: String? = null

}

fun Any?.toString(): String {
    return if (this == null) "Value is null" else "Value is not null"
}

fun main(args: Array<String>) {
    println(ExtensionExample().name.toString())
}

prints "Value is null", as you wanted.

Try it online!


Note that you cannot hide a member function using an extension function. That is,

class Test {

    fun a() {
        println("a")
    }

}

fun Test.a() {
    println("b")
}

...
Test().a()

will result in "a" being printed.

The only reason why your Any?.toString works (after being moved out of the class) is that Any? has no members as it is not a class, but a nullable type with the class Any. The already existing toString method is also an extension, so yours is not hidden by any members.

like image 122
Salem Avatar answered Nov 11 '25 17:11

Salem