Functions defined in Kotlin companion objects are often seen as the 'equivalent' of static methods in Java. Although there are some similarities, there are also some caveats you should be aware of. For example, how to use method references (or, to be pedantic: function references) to refer to functions defined in a companion object.

We define the following class Foo, which has an instance method named multiply. This method multiplies the passed Int argument by 2. Inside the class we define a companion object which contains the same method, but with different behavior (it multiplies the argument by 4 instead of 2).

class Foo {

    fun multiply(i: Int) = i * 2

    companion object {
        fun multiply(i: Int) = i * 4
    }
}

Calling the correct multiply function directly is of course straightforward:

// Calling the instance function
val foo = Foo()
println(foo.multiply(1)) // Prints: 2

// Calling the companion object function
println(Foo.multiply(1)) // Prints: 4

However, referencing the functions, e.g. to pass it to the map() function to map a Collection of Ints, works differently than expected, coming from Java:

// Referencing the instance function
val result = listOf(1, 2, 3)
        .map(foo::multiply)
        .joinToString()
println(result) // Prints: 2, 4, 6

// Referencing the companion object function
val result = listOf(1, 2, 3)
        .map(Foo::multiply) // Does NOT compile!!!
        .joinToString()

Basically, a companion object is compiled as a singleton instance class with its own functions. So how do we reference those functions? There are two ways:

// Using the name of the companion object (Foo.Companion)
val result = listOf(1, 2, 3)
        .map(Foo.Companion::multiply)
        .joinToString()
println(result) // Prints: 4, 8, 12

// Using a shorthand notation
val result = listOf(1, 2, 3)
        .map((Foo)::multiply)
        .joinToString()
println(result) // Prints: 4, 8, 12

Compiled and tested with Kotlin version 1.3.50.

shadow-left