# Reflection and properties, checking for custom getters/setters

**URL:** <https://discuss.kotlinlang.org/t/reflection-and-properties-checking-for-custom-getters-setters/22457>\
**Category:** Support\
**Created:** [July 19, 2021, 8:46pm UTC](https://discuss.kotlinlang.org/t/reflection-and-properties-checking-for-custom-getters-setters/22457 "2021-07-19T20:46:08Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![frizzil](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/frizzil/32/7505_2.png) [@frizzil](https://discuss.kotlinlang.org/u/frizzil)\
**Post date:** [July 19, 2021, 8:46pm UTC](https://discuss.kotlinlang.org/t/reflection-and-properties-checking-for-custom-getters-setters/22457/1 "2021-07-19T20:46:08Z")

</div>

Hi all,

So I’m using reflection to scrape classes for annotated properties, which I then use to inject automatically loaded resources. This seems to be working well, but I have a question about getters and setters in this context: **Is there a way to determine if custom getter/setters exist on property?** I have a few use cases:

The first is for the sake of robust warnings. E.g. if the annotation allows the property to be mutated, but only if the user “promises” to make a callback, then I’d like to throw an exception if no custom setter is defined at all. It’s not perfect, but I believe this would capture the majority of cases someone declares a property as `var` but forgets to make the callback.

The second case is related to optimization. I’d actually like to use the `javaField` property directly when possible, because it exposes get/set methods that don’t allocate `vararg` arrays; however, whether it’s null is predicated only on the existence of a backing field, which can be true regardless of whether a custom getter/setter is defined. Hence the desire for a direct check.

Thoughts? I’m trying to minimize allocations as much as possible here - both to minimize GC overhead and maintain cache coherency, if at all possible. I can tolerate the reflective aspect the few times it is invoked, but I’d like to avoid having wrapper classes everywhere just to make an optional callback on mutations. Annotations, reflection and LOTS of documentation seemed like a decent way of going about this, but there are some pitfalls like I’ve described here.

---

<div class="post-metadata">

**Author:** ![broot](https://avatars.discourse-cdn.com/v4/letter/b/a88e57/32.png) [@broot](https://discuss.kotlinlang.org/u/broot)\
**Post date:** [July 20, 2021, 6:28pm UTC](https://discuss.kotlinlang.org/t/reflection-and-properties-checking-for-custom-getters-setters/22457/2 "2021-07-20T18:28:09Z")

</div>

Let’s use this for experimenting:

```auto
class Test {
    val foo: String = "foo"
    val bar: String get() = "bar"
    val baz: String = "baz"
        get() = field
}

```

`foo` has a default implementation that gets a backing field. `bar` has a custom implementation without a backing field. `baz` has a custom implementation that uses a backing field.

We can very easily verify whether some property is backed by a field:

```
println("foo.javaField: " + Test::foo.javaField) // not null
println("bar.javaField: " + Test::bar.javaField) // null
println("baz.javaField: " + Test::baz.javaField) // not null

```

What about `foo` vs `baz`? Well, if we look into the resulting bytecode we’ll see they’re actually identical. I believe there is nothing in the bytecode that could help distinguish them. Nothing, except one thing.

Fortunately, Kotlin compiler puts a lot of extra info about the compiled code into auto-generated `@Metadata` annotations. These annotations contain information like e.g. whether a class is a data class or… whether a property getter has default or custom implementation.

As data contained in `@Metadata` is encoded in a binary form, you need to use `kotlinx-metadata` library to read it. There are dragons ahead though, I think it works with JVM only and it is pretty much experimental. I was able to acquire the data we need with the following code:

```auto
fun main() {
    val meta = Test::class.java.getKotlinMetadata()
    val kmClass = (meta as KotlinClassMetadata.Class).toKmClass()

    kmClass.properties.forEach { prop ->
        println("name: " + prop.name)
        println("getter.IS_NOT_DEFAULT: " + Flag.PropertyAccessor.IS_NOT_DEFAULT(prop.getterFlags))
    }
}

fun Class<*>.getKotlinMetadata(): KotlinClassMetadata? {
    val meta = getAnnotation(Metadata::class.java) ?: return null
    val header = KotlinClassHeader(
        kind = meta.kind,
        metadataVersion = meta.metadataVersion,
        data1 = meta.data1,
        data2 = meta.data2,
        extraString = meta.extraString,
        packageName = meta.packageName,
        extraInt = meta.extraInt,
    )
    return KotlinClassMetadata.read(header)
}

```

Output:

```auto
name: bar
getter.IS_NOT_DEFAULT: true
name: baz
getter.IS_NOT_DEFAULT: true
name: foo
getter.IS_NOT_DEFAULT: false

```

There is quite a lot of boilerplate code above, especially converting `Metadata` object to `KotlinClassHeader`. This is pretty weird to me, but I didn’t find a straightforward way to just load `@Metadata` of a class. Maybe I miss something.

---

<div class="post-metadata">

**Author:** ![frizzil](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/frizzil/32/7505_2.png) [@frizzil](https://discuss.kotlinlang.org/u/frizzil)\
**Post date:** [July 20, 2021, 6:50pm UTC](https://discuss.kotlinlang.org/t/reflection-and-properties-checking-for-custom-getters-setters/22457/3 "2021-07-20T18:50:33Z")

</div>

Wow, this is probably exactly what I needed, thanks! I’ll have to do some research, particularly on the JVM-only front, but if the library isn’t big I think this will do nicely.
