What’s the purpose of those *Ref types? What role do they play in the kotlin world?
I always see them when doing reverse-engineer, but there isn’t a single comment explaining their usages in the source code of kotlin, and Google only returns a bunch of java.lang.NoClassDefFoundError questions.
They are needed to provide a “mutable reference”. See this code:
fun foo() {
var s = "hello"
val r = Runnable { s = "world" }
}
We modify s in the lambda. It looks trivial from the source code perspective, but if we think for a second what’s happening there, we modified s from an entirely separate class, executed in a different context than foo, so how could it modify a local variable of foo? In this case the Kotlin compiler creates a thin wrapper over the string and passes it to the lambda. Lambda can modify the value stored inside the wrapper, and foo sees the change, because it also accesses the string through the wrapper. This wrapper is Ref$ObjectRef.
BTW, for the same reason a similar code in Java doesn’t compile:
public static void foo() {
var s = "hello";
var r = (Runnable) () -> {
s = "world"; // doesn't compile
};
}
Java disallow to modify variables belonging to outside scope inside closures. This is technically impossible to do without introducing some kind of a wrapper.