# How are "AnnotationRetention.BINARY" annotations represented in bycode?

**URL:** https://discuss.kotlinlang.org/t/how-are-annotationretention-binary-annotations-represented-in-bycode/29550
**Category:** Uncategorized
**Created:** [November 21, 2024, 12:10am UTC](https://discuss.kotlinlang.org/t/how-are-annotationretention-binary-annotations-represented-in-bycode/29550 "2024-11-21T00:10:41Z")
**Posts on this page:** 4
**Page:** 1

<div class="post-metadata">

### Author: ![andreilisun](https://avatars.discourse-cdn.com/v4/letter/a/f08c70/32.png) [@andreilisun](https://discuss.kotlinlang.org/u/andreilisun)
#### Post date: [November 21, 2024, 12:10am UTC](https://discuss.kotlinlang.org/t/how-are-annotationretention-binary-annotations-represented-in-bycode/29550/1 "2024-11-21T00:10:41Z")

</div>

I’m trying to figure out how annotations with “AnnotationRetention.BINARY” retention are represented in bytecode.

Annotations with “AnnotationRetention.RUNTIME” retention are explicitly added to bytecode.

Annotations with “AnnotationRetention.BINARY” retention policy are not explicitly added to bytecode. However, it seems like some tools can read them from bytecode.

E. g., “androidx.annotation.RequiresApi” annotation has “AnnotationRetention.BINARY” retention. It is not seen in bytecode. However, it seems that tools like [Facebook’s RedEx](https://github.com/facebook/redex) can somehow read “RequiresApi” annotation.

UPD: Here is an example of the class:

```auto
class Test {
    companion object {
        @JvmStatic
        val testProp : Int = 0

        @RequiresApi(24)
        val testProp22 : Int = 0
    }
}

```

`@JvmStatic` is `AnnotationRetention.RUNTIME`  
` @RequiresApi` is `AnnotationRetention.BINARY`

For “@JvmStatic” I see the following in Android Studio dex byte code viewer:

```auto
.method public static synthetic getTestProp$annotations()V
    .registers 0
    .annotation runtime Lkotlin/jvm/JvmStatic;
    .end annotation

    return-void
.end method

```

However, there is nothing for @RequiresApi annotation.

I also tried [Konloch bytecode-viewer](https://github.com/Konloch/bytecode-viewer) and the result is the same.

---

<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: [November 21, 2024, 2:41am UTC](https://discuss.kotlinlang.org/t/how-are-annotationretention-binary-annotations-represented-in-bycode/29550/2 "2024-11-21T02:41:25Z")

</div>

I don’t know the answer, but I would check the `Metadata` annotation to the enclosing class. Kotlin puts some internal stuff there.

edit:  
Actually, did you check they are not present in the bytecode? I ask because the most obvious explanation would be that they are the same as Java’s `RetentionPolicy.CLASS` - so they are stored in the bytecode, but ignored by JVM at runtime.

---

<div class="post-metadata">

### Author: ![andreilisun](https://avatars.discourse-cdn.com/v4/letter/a/f08c70/32.png) [@andreilisun](https://discuss.kotlinlang.org/u/andreilisun)
#### Post date: [November 21, 2024, 3:26am UTC](https://discuss.kotlinlang.org/t/how-are-annotationretention-binary-annotations-represented-in-bycode/29550/3 "2024-11-21T03:26:39Z")

</div>

@broot, thanks for you comment. `Metadata` was my guess too, but unfortunately I didn’t find any tool to “decode” metadata and prove that the annotation is somewhere there.

> Actually, did you check they are not present in the bytecode?

I updated my post. I tried different viewers to check the bytecode.

---

<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: [November 21, 2024, 11:10am UTC](https://discuss.kotlinlang.org/t/how-are-annotationretention-binary-annotations-represented-in-bycode/29550/4 "2024-11-21T11:10:55Z")

</div>

Frankly speaking, I don’t think it has anything to do with Kotlin. It is rather Android. In the JVM bytecode both annotations are clearly present:

```kotlin
@Target(AnnotationTarget.FUNCTION)
@Retention(AnnotationRetention.RUNTIME)
annotation class RuntimeAnnotation

@Target(AnnotationTarget.FUNCTION)
@Retention(AnnotationRetention.BINARY)
annotation class BinaryAnnotation

object MyTest {
    @RuntimeAnnotation
    fun testRuntime() = Unit

    @BinaryAnnotation
    fun testBinary() = Unit
}

```

```auto
  public final void testRuntime();
    descriptor: ()V
    flags: (0x0011) ACC_PUBLIC, ACC_FINAL
    Code:
      stack=0, locals=1, args_size=1
         0: return
      LineNumberTable:
        line 41: 0
      LocalVariableTable:
        Start Length Slot Name Signature
            0 1 0 this LMyTest;
    RuntimeVisibleAnnotations:
      0: #12()
        RuntimeAnnotation

  public final void testBinary();
    descriptor: ()V
    flags: (0x0011) ACC_PUBLIC, ACC_FINAL
    Code:
      stack=0, locals=1, args_size=1
         0: return
      LineNumberTable:
        line 44: 0
      LocalVariableTable:
        Start Length Slot Name Signature
            0 1 0 this LMyTest;
    RuntimeInvisibleAnnotations:
      0: #14()
        BinaryAnnotation

```

I suspect runtime invisible annotations may be somehow separated or removed in the resulting dex, most probably in order to improve the performance.
