Does returning an object expression (sometimes?) leak a reference to the outer class instance?

A method (fun) returns an implementation of a simple interface, which necessarily references a member of the outer class.
It’s more concise and readable to write it (contrived):

class A(val x: Int) {
  fun foo(): Interfoo {
    return object: Interfoo {
      override fun meth() = x
    }
  }
}

But to (maybe?) avoid the anonymous object maintaining a reference to the instance of class A, I could implement fun foo differently:

fun foo(): Interfoo {
  class B(val x = x): Interfoo {
    override fun meth() = x
  }
  return B()
}

Am I right that the former would maintain a reference to the the instance of A, while the latter would not? Is there another way to avoid leaking a reference to the instance of A?

1 Like

How about…

class A(val x: Int) {
  fun foo(): Interfoo {
    val x = this.x           // capture local copy of x
    return object: Interfoo {
      override fun meth() = x
    }
  }
}

Yeap. One way is what @naxymatt proposed:

class A(val x: Int) {
	fun foo(): Interfoo {
		val x = x // copy property value to local variable
		return object : Interfoo {
			override fun meth() = x
		}
	}
}

or another approach:

class A(val x: Int) {
	fun foo(): Interfoo = object : Interfoo {
		private val x = this@A.x // copy property value and assign it to inner object property
		
		override fun meth() = x
	}
}

from Kotlin 1.4+ this syntax will also be valid:

class A(val x: Int) {
	fun foo(): Interfoo {
		val x = x // copy property value to local variable
		return Interfoo { x }
	}
}
2 Likes

If, and only if, Interfoo is defined as a functional interface (i.e. as a fun interface)

I know :slight_smile: I simply assumped that it would a functional interface as you said.

1 Like