我正在玩 Kotlin 并发现了有趣的行为。 所以假设我想要某种工厂:
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()
}
java文件中定义的ChangeListener
:
interface ChangeListener {
void notifyChange(Object element);
}
然后我尝试像这样从 Java 中使用它:
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));
结果是:
createNew: a == b -> false
createTheSame: c == d -> true
我能理解为什么 createNew
会因为关闭而返回新的对象。
但为什么我从 createTheSame
方法接收到相同的实例?
附言我知道上面的代码不是惯用的:)
最佳答案
这与性能有关。创建更少的对象显然对性能更好,所以这就是 Kotlin 试图做的事情。
对于每个 lambda,Kotlin 生成一个实现适当接口(interface)的类。因此,例如以下 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 范围之外的变量,这将不起作用:单例实例无法访问该变量。
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
不同的原因。
关于android - Kotlin 从工厂方法返回相同的对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44291217/