Kotlin returns the same object from Factory method

I play with Kotlin and found interesting behavior. So let's say I want to have some kind of Factory:

internal interface SomeStupidInterface {
    companion object FACTORY {
       fun createNew(): ChangeListener {
            val time = System.currentTimeMillis()
            return ChangeListener { element -> Log.e("J2KO", "time " + time) }
        }

        fun createTheSame(): ChangeListener {
            return ChangeListener { element -> Log.e("J2KO", "time " + System.currentTimeMillis()) }
        }
    }

    fun notifyChanged()
}

where is ChangeListenerdefined in the java file:

interface ChangeListener {
    void notifyChange(Object element);
}

And then I try to use it with Java like this:

ChangeListener a = SomeStupidInterface.FACTORY.createNew();
ChangeListener b = SomeStupidInterface.FACTORY.createNew();
ChangeListener c = SomeStupidInterface.FACTORY.createTheSame();
ChangeListener d = SomeStupidInterface.FACTORY.createTheSame();
Log.e("J2KO", "createNew a == b -> " + (a == b));
Log.e("J2KO", "createTheSame c == d -> " + (c == d));

Results:

createNew: a == b -> false
createTheSame: c == d -> true

I can understand why createNewreturns new objects due to closure. But why am I getting the same instance from a method createTheSame?

PS I know that the code above is not idiomatic :)

+4
source share
3 answers

First note: your sample code does not work as it is: the interface must be written in Java to be available for use with SAM constructors.

, , . Lambdas ( , SAM) ( ). , . , - , . , , . ( Kotlin in Action .)

- , object:

fun createNotQUiteTheSame(): ChangeListener {
    return object : ChangeListener {
        override fun notifyChanged(element: Any?) {
            println("time " + System.currentTimeMillis())
        }
    }
}

. , IntelliJ SAM:

fun createNotQUiteTheSame(): ChangeListener {
    return ChangeListener { println("time " + System.currentTimeMillis()) }
}

, , .

, , , , . , , , object. , , id.

+4

. , , , .

Kotlin , . , , :

fun create() : () -> Unit {
  return { println("Hello, World!") }
}

- :

Function0 create() {
  return create$1.INSTANCE;
}

final class create$1 implements Function0 {

  static final create$1 INSTANCE = new create$1();

  void invoke() {
    System.out.println("Hello, World!");
  }
} 

, .


, lamdba, : singleton .

fun create(text: String) : () -> Unit {
  return { println(text) }
}

create , text:

Function0 create(String text) {
  return new create$1(text);
}

final class create$1 implements Function0 {

  final String text;

  create$1(String text) {
    this.text = text;
  }

  void invoke() {
    System.out.println(text);
  }
} 

a b , c d .

+6

, SAM Kotlin.

, SAM , , .

, Java interop; Kotlin , Kotlin , , .

, , . - , .

internal interface SomeStupidInterface {
    interface ChangeListener {
        fun notifyChanged(element: Any)
    }

    companion object FACTORY {
        fun createNew(): ChangeListener {
            val time = System.currentTimeMillis()
            return object : ChangeListener {
                override fun notifyChanged(element: Any) {
                    println("J2KO" + "time " + time)
                }
            }
        }

        fun createTheSame(): ChangeListener {
            return object : ChangeListener {
                override fun notifyChanged(element: Any) {
                    println("J2KO" + "time " + System.currentTimeMillis())
                }
            }
        }
    }

    fun notifyChanged()
}

IntelliJ IDEA .

-1

Source: https://habr.com/ru/post/1678283/


All Articles