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

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 can somehow read “RequiresApi” annotation.

UPD: Here is an example of the class:

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:

.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 and the result is the same.

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.

@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.