Introduction to Annotations.
What are Annotations➔ Annotations are structured information added to program source code➔ Annotations associated meta-information with definitions➔ They can be attached to any variable, method, expression, or another program element Like comments, they can be sprinkled throughout a program➔ Unlike comments, they have structure, thus making them easier to machine process.
2. AGENDA
●
What is Annotations.
Why have Annotations.
Syntax of Annotations.
Types Of Annotation
Standard Annotations.
Example of Annotation
Writing your own annotations
Comparison of scala annotation with java.
3. What is Annotations
➔
Annotations are structured information added to program source
code.
➔
Annotations associate meta-information with definitions.
➔
They can be attached to any variable, method, expression, or
other program element
➔
Like comments, they can be sprinkled throughout a program .
➔
Unlike comments, they have structure, thus making them easier
to machine process.
4. Why have Annotations
Meta Programming Tools : They are programs that take other programs as
input.
Task performed :
1. Automatic generation of documentation as with Scaladoc.
2. Pretty printing code so that it matches your preferred style.
3. Checking code for common errors such as opening a file but, on some
control paths, never closing it.
4. Experimental type checking, for example to manage side effects or
ensure ownership properties.
5. Improvement after using Annotations :
1. Automatic generation of documentation as with Scaladoc.
➔
A documentation generator could be instructed to document certain
methods as deprecated.
2. Pretty printing code so that it matches your preferred style.
➔
A pretty printer could be instructed to skip over parts of the program
that have been carefully hand formatted.
6. Improvement after using Annotations :
3. Checking code for common errors such as opening a file but, on some
control paths, never closing it.
➔
A checker for non-closed files could be instructed to ignore a particular
file that has been manually verified to be closed.
4. Experimental type checking, for example to manage side effects or
ensure ownership properties.
➔
A side-effects checker could be instructed to verify that a specified
method has no side effects.
7. Syntax of annotations
Annotations are allowed on any kind of declaration or definition, including
vals, vars, defs, classes, objects, traits, and types.
●
Method Annotation: @deprecated def bigMistake() = //..
●
Classes Annotation: @serializable class C { ... }
●
Expressions Annotation: (e: @unchecked) match {
// non-exhaustive cases...
}
●
Type Annotation : String @local
●
Variable Annotation : @transient @volatile var m: Int
8. Syntax of annotations
Annotations have a richer general form:
@annot(exp1 , exp2 , ...) {val name1 =const1 , ..., val namen =constn }
●
The annot specifies the class of annotation.
●
The exp parts are arguments to the annotation
●
The name=const pairs are available for more complicated annotations.
●
These arguments are optional, and they can be specified in any order.
●
To keep things simple, the part to the right-hand side of the equals sign
must be a constant.
9. Types of Annotations
●
No arguments Annotations :
For no arguments annotations like @deprecated ,leave off the parentheses,
but we can write @deprecated() .
●
Argument annotations
For annotations that do have arguments, place the arguments in
parentheses. example, @serial(1234) .
10. Types of Annotations
●
The precise form of the arguments depends on the particular annotation
class.
●
Most annotation processors allow only constants such as 123 or "hello".
●
The compiler itself supports arbitrary expressions, however, so long as they
type check.
for example, @cool val normal = "Hello"
@coolerThan(normal) val fonzy = "Heeyyy"
11. Standard annotations
Deprecation : (@deprecated)
●
This is used with class and methods.
●
When anyone calls that method or class will get a deprecation warning.
●
Syntax : @deprecated def bigMistake() = //..
Volatile Fields : (@volatile)
●
This annotations helps programmers to use mutable state in their
concurrent programs.
12. Standard annotations
●
It informs the compiler that the variable in question will be used by multiple
threads
●
The @volatile keyword gives different guarantees on different platforms.
●
On the Java platform, it behaves same as Java volatile modifier.
●
Binary serialization :
●
It means to convert objects into a stream of bytes and vice versa.
●
Many languages include a framework for binary serialization.
13. Standard annotations
●
Scala does not have its own serialization framework.
●
Scala provides 3 annotations that are useful for a variety of frameworks.
1. (a) The first annotation indicates whether a class is serializable at all
(b) Add a @serializable annotation to any class which we would like to
be serializable.
2. (a) The second annotation helps deal with serializable classes changing as
time goes by.
(b) We can attach a serial number to the current version of a class by
adding an annotation like @SerialVersionUID(<longlit>)
14. Standard annotations
(c) If we want to make a serialization-incompatible change to our class,
then we can change the version number.
3. (a) Scala provides a @transient annotation for fields that should not be
serialized at all.
(b) The framework should not save the field even when the surrounding
object is serialized.
Automatic get and set methods : (@scala.reflect.BeanProperty)
●
Scala code normally does not need explicit get and set methods for fields.
15. Standard annotations
●
Some platform-specific frameworks do expect get and set methods.
●
For that purpose, Scala provides the @scala.reflect.BeanProperty
annotation.
●
The generated get and set methods are only available after a compilation
pass completes.
●
We cannot call these get and set methods from code we compile at the same
time as the annotated fields.
●
This should not be a problem in Scala, because in Scala code we can access
the fields directly.
16. Standard annotations
●
This feature is intended to support frameworks that expect regular
get and set methods, and typically we do not compile the framework and
the code that uses it at the same time.
Unchecked : (@unchecked)
The @unchecked annotation is interpreted by the compiler during pattern
●
matches.
●
It tells the compiler not to worry if the match expression seems to
leave out some cases.
17. Example of annotations
Scala Class : (Reader.scala)
package ppt
import java.io._
class Reader(fname: String) {
private val in = new BufferedReader(new FileReader(fname))
@throws(classOf[IOException])
def read() = in.read()
}
Java Class :(AnnotaTest.java)
package test;
import ppt.Reader; // Scala class !!
public class AnnotaTest {
public static void main(String[] args) {
try {
Reader in = new Reader(args[0]);
int c;
while ((c = in.read()) != -1) {
System.out.print((char) c);
} } catch (java.io.IOException e) {
System.out.println(e.getMessage());
} }}
18. Example of annotations
Scala Class : (Reader.scala)
package ppt
import java.io._
class Reader(fname: String) {
private val in = new BufferedReader(new FileReader(fname))
@throws(classOf[IOException])
def read() = in.read()
}
Java Class :(AnnotaTest.java)
package test;
import ppt.Reader; // Scala class !!
public class AnnotaTest {
public static void main(String[] args) {
try {
Reader in = new Reader(args[0]);
int c;
while ((c = in.read()) != -1) {
System.out.print((char) c);
} } catch (java.io.IOException e) {
System.out.println(e.getMessage());
} }}
19. Example of annotations
Scala Class : (Person.scala)
Package my.scala.stuff;
import scala.reflect.BeanProperty
class Person {
@BeanProperty
var name = "Dave"
var age = 36
}
Java Class :(UsingBeanProperty.java)
package my.java.stuff;
import my.scala.stuff.*;
public class UsingBeanProperty {
public UsingBeanProperty(Person p) {
// Scala has added this method for us
System.out.println(p.getName());
// Since we didn't annotate "age", we can't do this:
System.out.println(p.getAge()); // compile error!
}
}
20. Writing your own annotations
To make an annotation that is visible to Java reflection, we must use Java notation and
compile it with javac.
Example :
Java class ; (Ignore.java)
import java.lang.annotation.*;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Ignore { }
Scala Object : (Tests.scala)
object Tests {
@Ignore
def testData = List(0, 1, -1, 5, -5)
def test1 {
assert(testData == (testData.head :: testData.tail))
}
def test2 {
assert(testData.contains(testData.head))
}}
21. Writing your own annotations
To see when these annotations are present,use the Java reflection APIs.
Example :
Tests.getClass.getMethods foreach {
method =>
if (method.getAnnotation(classOf[Ignore]) == null &&
method.getName.startsWith("test"))
{
println(method)
}}
Output :
public void ppt.Tests$.test2()
public void ppt.Tests$.test1()