Reputation: 4015
I cannot find how to pass the reference of the objects so that I can let them point to a new location in the memory. How to do this in Kotlin?
Code:
class Parent {
}
class Child : Parent {
}
class GlobalDataHolder {
var globalChildVriable: Child? = null // imagine this is a static variable and can be accessed anywhere
}
class Activity() {
var variable1 = Child()
Helper.init(variable1, GlobalDataHolder.globalChildVriable) // inside onCreate()
}
class Helper {
initStuff(variable1: Parent, globalVariable: Parent?) {
if (globalVariable == null) {
globalVariable = variable1 // error saying val cannot be re-assigned
}
else {
variable1 = globalVariable!!
}
}
}
I want variable1 and globalVariable to be modifiable. So the original owners of them will have the latest values.
Upvotes: 4
Views: 10572
Reputation: 6495
Kotlin (and Java) do not natively support reference types like C/C++ do.
However, kotlin does have property and functional types.
A property is basically just a combination of 2 functions (a getter and a setter). You can pass properties as arguments and, with reflection, call their getter setter individually from a different context.
Updated (compilable) code:
open class Parent { }
open class Child : Parent() { }
var globalVariable: Child? = null
class Activity() {
var localVariable = Child()
init {
Helper.initStuff(this::localVariable, ::globalVariable)
}
}
object Helper {
fun initStuff(localProperty: KMutableProperty0<out Parent>, globalProperty: KMutableProperty0<out Parent?>) {
val globalVariable = globalProperty.call()
val variable1 = localProperty.call()
if (globalVariable == null) {
globalProperty.setter.call(variable1)
}
else {
variableProperty.setter.call(globalVariable)
}
}
}
Upvotes: 3
Reputation: 12167
Such problems can "always" be solved by introducing one more level of abstraction. You can for example add a new interface VarHolder
which is responsible for getting/setting the contained variable.
interface VarHandle<E> {
var variable: E
}
class Activity() {
var variable1 = Child()
fun onCreate() {
Helper.initStuff(object : VarHandle<Child> {
override var variable: Child
get() = variable1
set(value) { variable1 = value }
}, object : VarHandle<Child?> {
override var variable: Child?
get() = GlobalDataHolder.globalChildVariable
set(value) { GlobalDataHolder.globalChildVariable = value }
})
}
}
object Helper {
fun initStuff(localVarHolder: VarHandle<Child>, globalVarHolder: VarHandle<Child?>) {
val globalVar = globalVarHolder.variable
val localVar = localVarHolder.variable
if (globalVar == null) {
globalVarHolder.variable = localVar
}
else {
localVarHolder.variable = globalVar
}
}
}
Upvotes: 1