Scala | Annotation
Scala Annotations are metadata added to the program source code. Annotations are allowed on any kind of definition or declaration including vals, vars, classes, objects, traits, defs and types. Annotations are used to associate meta-information with definitions.
Syntax:
@annot(exp_{1}, exp_{2}, …) {val name_{1}=const_{1}, …, val name_{n}=const_{n}}
All annotations must include “annot” as it specifies the annotations class. The annotations which have no arguments uses an empty().
Predefined annotations in Scala are built-in scala annotations which associate meta-information with definition. Some of the predefined scala annotations are:
- Java Platform Annotations:
- @transient:It is used to mark a field to be non-persistent.
- @volatile: It is used to mark a field which can change its value outside the control of the program.
- @SerialVersionUID(): It attaches a serial version identifier( a long constant) to a class.
Example:private final static SerialVersionUID = < longlit >
- Java Beans Annotations:
- @scala.beans.BeanProperty: This annotation, when prefixed to a definition of some variable X, causes getter and setter methods getX, setX in the Java bean style to be added in the class containing the variable. first letter of a variable seems capitalized after using the get or set.
- @scala.beans.BooleanBeanProperty: This annotation is equivalent to scala.reflect.BeanProperty, but the generated getter method is named isX not getX.
- Deprecation Annotations:
-
@deprecated(message: , since: ): This annotation is used to mark a definition as deprecated. Deprecated warnings are suppressed in code that belongs itself to a definition that is labeled deprecated.
Syntax:@deprecated("deprecation message", "release # which deprecates method")
Example:
// Scala program of Deprecation Annotations
import
scala.deprecated;
// Creating object
object
GFG
{
// Main method
def
main(args
:
Array[String])
{
// Define Deprecation Annotations:
@
deprecated
def
printMessage()
=
{
println(
"This method is deprecated"
)
}
printMessage()
}
}
Output:
This method is deprecated
-
@deprecated(message: , since: ): This annotation is used to mark a definition as deprecated. Deprecated warnings are suppressed in code that belongs itself to a definition that is labeled deprecated.
- Scala Compiler Annotations:
- @uncheckedStable: This annotation when applied to a value declaration or definition, allows the defined value to appear in a path, even if its type is volatile.
Syntax:@annotation.unchecked.uncheckedStable val x: A with B = null
Example:
// Scala program of uncheckedStable
// Compiler Annotations
import
scala.deprecated;
// Creating object
object
GFG
{
// Main method
def
main(args
:
Array[String])
{
trait
A
{
type
T
=
Int
}
trait
B
{
type
T
<:
String
}
def
f(b
:
B)(t
:
b.T)
=
t.length
// Define Compiler Annotations
@
annotation.unchecked.uncheckedStable
val
x
:
A
with
B
=
null
// legal because x is A
val
y
:
x.T
=
0
f(x)(y)
}
}
Output:
java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
- @tailrec:This annotation ensures that a method is tail-recursive. Tail-recursion can keep memory requirements constant.
Syntax:@tailrec
Example:
// Scala program of Compiler Annotations
// of tail recursion
import
scala.annotation.tailrec
// Creating object
object
GFG
{
// Main method
def
main(args
:
Array[String])
{
// Define factorial method
def
factorial(x
:
Int)
:
Int
=
{
// Compiler Annotations of tail recursion
@
tailrec
def
factorialHelper(x
:
Int, accumulator
:
Int)
:
Int
=
{
if
(x
==
1
) accumulator
else
factorialHelper(x -
1
, accumulator * x)
}
factorialHelper(x,
1
)
}
println(factorial(
5
))
}
}
Output:
120
- @uncheckedStable: This annotation when applied to a value declaration or definition, allows the defined value to appear in a path, even if its type is volatile.
User-defined annotations associate meta-information with definitions. For a class, Class files hold an annotation class instances which class inherits from the trait Scala.ClassfileAnnotation. the instances are visible to the Scala type-checker for every compilation unit where we access the annotated symbol and class inherits from the trait scala.StaticAnnotation.
Syntax:
// needed for @Documented import java.lang.annotation.*; @Documented public @interface impure {}