Table of contents
1.
Introduction
2.
Kotlin Annotations
2.1.
Declaring an Annotation
2.2.
Kotlin Meta-Annotations
2.3.
@Target
2.4.
@Retention
2.5.
@Repeatable
2.6.
@MustBeDocumented
3.
Annotate a constructor
4.
JVM-Related Annotations
5.
FAQs
6.
Key Takeaways
Last Updated: Mar 27, 2024

Kotlin Annotations

Author Vasu Bansal
0 upvote
Career growth poll
Do you think IIT Guwahati certified course can help you in your career?

Introduction

In this blog, we'll go over the basics of Kotlin annotations. Annotations are a way to embed metadata in your code. You will learn how to use them and how to make and personalize your own custom annotations. After that, we'll talk about JVM-related annotations and their different use cases. In the next section, we will start by understanding the utility and use of Kotlin Annotations.

Kotlin Annotations

Annotations are used at compile time to attach metadata to classes, interfaces, parameters, etc. The compiler can apply annotations, which reflect at runtime. According to the annotation values, we can change the meaning of the data or program.

Declaring an Annotation

Annotation is declared by appending the annotation modifier to a class name. Defining a class first and then adding the annotation keyword before it is a must. Annotation declarations cannot include any code by definition.

annotation class TestClass

The annotation declaration shown above depicts a simple annotation with no input parameters. One can use the following syntax to declare an annotation with parameters.

annotation class Calc(val sum: Integer)

Kotlin Meta-Annotations

We should describe which code components our custom annotations may apply to and where we should keep them while declaring the annotations. Meta-annotations are annotations that define meta-information (additional information).

Some of the meta-annotations are listed as follows:

@Target

This meta-annotation indicates the code elements to which this annotation could refer. It has a mandatory parameter that must be either an instance or an array of the AnnotationTarget enumeration. Thus one can specify the elements to which they want to apply the annotation. Some elements include LOCAL_VARIABLE, PROPERTY_GETTER, PROPERTY_SETTER, VALUE_PARAMETER, CONSTRUCTOR, etc.

The following is a sample program to demonstrate @Target annotation.

@Target(AnnotationTarget.CONSTRUCTOR)
annotation class TargetConstructorAnnotation

class Ninja @TargetConstructorAnnotation constructor(val ninja_id:Int){
    fun display(){
        println("Example of constructor annotation using @Target")
        println("Ninja ID is $ninja_id")
    }
}
fun main(){
    val obj = Ninja(1)
    obj.display()
}

Output:

Example of constructor annotation using @Target
Ninja ID is 1

@Retention

@Retention indicates whether the annotation should be stored in the .class file and whether it should be seen in the reflection. Its required parameter must be an AnnotationRetention enumeration instance with the following elements, SOURCE, BINARY and RUNTIME. The default value for the @Retention is RUNTIME in the Kotlin programming language.

The following is a sample program to demonstrate @Retention annotation.

@Retention(AnnotationRetention.RUNTIME)
annotation class RetentionAnnotation

// Annotating main function
@RetentionAnnotation fun main(){
    println("Example of @Retention annotation")
}

Output:

Example of @Retention annotation

@Repeatable

If an element can have several annotations of the same kind, it is marked as @Repeatable. There are no parameters for this meta-annotation.

The following is a sample program to demonstrate @Repeatable annotation.

@Repeatable
@Retention(AnnotationRetention.SOURCE) // As per the latest Kotlin versions, the Repeatable annotation can be used with Retention policy set as source
annotation class RepeatableAnnotationExample (val name: String)

@RepeatableAnnotationExample("Coding")
@RepeatableAnnotationExample("Ninjas")
fun test(){
    println("Example of repeatable annotation being applied on the test function")
}

fun main(){
    test()  
}

Output:

Example of repeatable annotation being applied on the test function

@MustBeDocumented

The annotation's documentation must be included in the generated documentation if @MustBeDocumented is true. This meta-annotation, too, takes no parameters.

The following is a sample program to demonstrate @MustBeDocumented annotation.

@MustBeDocumented
annotation class MustBeDocumentedExample
 
// Annotating main function using @MustBeDocumented annotation
@MustBeDocumentedExample fun main(){
    println("Example of @MustBeDocumented annotation")
}

Output:

Example of @MustBeDocumented annotation

Annotate a constructor

It's also feasible to annotate a class's constructor. This is accomplished by inserting the annotation before the constructor declaration, as shown below.

class TestClass @Inject constructor(dependency: MyDependency){
        // Logic
}

Annotations can have constructors that take parameters. Strings, enums, classes are some allowed parameter types. The JVM does not allow null to be stored as an annotation attribute value; therefore, the annotation parameters cannot have nullable types. To read more about constructors in Kotlin, refer to the blog Kotlin Constructors on the Coding Ninjas Website.

Use a Kotlin class (KClass) as an annotation input if you need to specify a class as an argument of an annotation. The Kotlin compiler will transform it to a Java class automatically, allowing Java code to access the annotations and parameters as usual.

import kotlin.reflect.KClass

annotation class Ann(val arg1: KClass<*>, val arg2: KClass<out Any>)

@Ann(String::class, Int::class) class TestClass

JVM-Related Annotations

The Kotlin annotations listed below allow us to tailor how they're utilised in Java code:

@JvmName - It changes the name of the created Java method or field.

@JvmStatic - It specifies whether the generated Java method or field should be static or not.

@JvmOverloads - It specifies that the Kotlin compiler should generate overload functions substituting default parameters. 

@JvmField - It specifies that the generated Java field should be a public one with no getter/setter.

FAQs

  1. What is the use of JVMName annotation?
    The annotation @JvmName changes the name of a Java function in the bytecode.
     
  2. How are Inject and Autowired annotations different from each other?
    The @Autowired and @Inject annotation are used for auto-wiring in the Spring framework. The main difference is that @Inject is a standard annotation for dependency injection and @Autowired is spring specific.
     
  3. What is @inject annotation in Kotlin?
    The component declared with the @Component annotation is the fundamental element of Kotlin Inject. For custom dependencies, @Inject annotation can annotate the class. 

Key Takeaways

Cheers if you reached here!! In this blog, we have learned about annotations in Kotlin and saw different types of annotations, including custom annotations. Go ahead and read the blog Kotlin Regex on the Coding Ninjas website to understand regular expressions in Kotlin.

Yet there is never an end to the learning process, so check out our Android Development Course on the Coding Ninjas Website to learn everything you need to know about Android development and how to design the applications of the future. Until then, good luck!!

Live masterclass