Created
July 15, 2020 08:14
-
-
Save lemnik/1c925028ceba324554d71f7927cf3958 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// JVM Delegate to expose a private field, and bypass any Kotlin getters & setters | |
// This is a horrible abuse of reflection and should never be used, unless you absolutely have to have it. | |
import java.lang.reflect.Field | |
import kotlin.reflect.KProperty | |
class ExposeDelegate<T> { | |
private fun field(thisRef: Any?, property: KProperty<*>): Field? { | |
if (thisRef == null) return null | |
val name = property.name | |
val field = thisRef::class.java.getDeclaredField(name) | |
field.isAccessible = true | |
return field | |
} | |
operator fun getValue(thisRef: Any?, property: KProperty<*>): T? { | |
return field(thisRef, property)?.get(thisRef) as T? | |
} | |
operator fun setValue(thisRef: Any?, property: KProperty<*>, value: T?) { | |
field(thisRef, property)?.set(thisRef, value) | |
} | |
} | |
// convenience method for readbility | |
fun <T> expose() = ExposeDelegate<T>() | |
// Useage Example ------------------------------------------------------------------------------------------------------- | |
data class FooBar(private val value: String) | |
var FooBar.value by expose<String>() | |
fun main() { | |
val fooBar = FooBar("Hello") | |
println(fooBar) | |
fooBar.value = "Hello World" | |
println(fooBar) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment