You are on page 1of 41

JAVA Annotation

Problem [1]
public class Person {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public static void main(String[] args) {
Person p = new Person();
p.setName("Daniel");
System.out.println("Name: "+p.getName());
}
}

Problem [2]
@Data
public class Person {
private String name;
public static void main(String[] args) {
Person p = new Person();
p.setName("Daniel");
System.out.println("Name:
"+p.getName());
}
}

Problem [3]
public class MyUtils
{
private static final Logger log =
LoggerFactory.getLogger(MyUtils.class);
public void myAlgorithm()
{
log.info("This is my algorithm.");
}
}

Problem [4]
@Slf4j
public class MyUtils
{
public void myAlgorithm()
{
log.info("This is my algorithm.");
}
}

Goal
Understanding how to Annotate.
Understanding how annotation
preprocessor work.
Understanding how Project Lombok
work.

Definition
Anotasi adalah catatan yg dibuat oleh
pengarang atau orang lain untuk
menerangkan, mengomentari, atau
mengkritik teks karya sastra atau
bahan tertulis lain. (KBBI)
A note by way of explanation or
comment added to a text or diagram.
(Oxford Dictionary)

Introduction

An annotation, in the Java computer


programming language, is a form of
syntactic metadata that can be added to
Java source code.
Classes, methods, variables, parameters
and packages may be annotated.
Java annotations can be reflective in that
they can be embedded in class files
generated by the compiler and may be
retained by the Java VM to be made
retrievable at run-time.

Annotation Example
@API
package com.djph.annotation.lombok1;
@Entity
public class MyObject
{
@NotNull
private String name;
@Autowired
public MyObject()
{
}
@Transactional
public void myMethod(@Valid Object obj)
{
}
}

History [1]
The Java platform has various ad-hoc
annotation mechanismsfor example,
the transient modifier, or the
@deprecated javadoc tag.
The general purpose annotation (also
known as metadata) facility was
introduced to the Java Community
Process as JSR-175 in 2002 and
approved in September 2004.

History [2]
Annotations became available in the
language itself beginning with version
1.5 of the JDK.
A provisional interface for compiletime annotation processing was
provided by the apt tool in JDK version
1.5, and was formalized through JSR269 and integrated into the javac
compiler in version 1.6.

Built-in annotations [1]

Annotations applied to Java code:

@Override
@Deprecated
@SuppressWarnings
@SafeVarargs (Since Java 7)
@FunctionalInterface (Since Java 8)

Built-in annotations [2]

Annotations applied to other


annotations:

@Retention
@Documented
@Target
@Inherited
@Repeatable (Since Java 8)

Built-in annotations (Example)


public class MyObject
{
@Override
public String toString()
{
return "MyObject{"+'}';
}
}

Custom annotations
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target
({
ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR,
ElementType.FIELD, ElementType.LOCAL_VARIABLE,
ElementType.METHOD, ElementType.PACKAGE,
ElementType.PARAMETER, ElementType.TYPE
})
@Retention(RetentionPolicy.RUNTIME) //RetentionPolicy.CLASS,
RetentionPolicy.RUNTIME
public @interface MyAnnotation
{
String value();
}

Custom annotation (Note) [1]

In annotations with a single element,


the element should be named value.
public @interface MyAnnotation {
String value();
}

If there is just one element named


value, then the name can be omitted.
@MyAnnotation(Im value of element value.")
public class MyObject { ... }

Custom annotation (Note) [2]

If no values, then no parentheses


public @interface NoValue { }
needed.
@NoValue
public class MyObject { ... }

It is also possible to use multiple


@Author(name = "Jane
Doe")same declaration.
annotations
on
the
@EBook
class MyClass { ... }

Custom annotation (Note) [3]

If the annotations have the same type,


then this is called a repeating
annotation. Repeating annotations are
supported as of the Java SE 8
@Author(name = "Jane Doe")
release.
@Author(name = "John Smith")
class MyClass { ... }

Where Annotations Can Be Used


in Java 8

Class instance creation expression:


new @Interned MyObject();

Type cast:
myString = (@NonNull String) str;

implements clause:
class UnmodifiableList<T> implements
@Readonly List<@Readonly T> { ... }

Thrown exception declaration:


void monitorTemperature() throws
@Critical TemperatureException { ... }

Access Annotations using


Reflection
Class clazz = MyObject.class;
Annotation[] atType = clazz.getAnnotations();
Annotation[] atField =
clazz.getField("myField").getAnnotations();
Annotation[] atMethod = clazz.getMethod("myMethod",
parameterTypes).getAnnotations();

Annotation Processor at Runtime


[1]
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface NotNull {
}

public class MyEntity {


@NotNull
public String name;
}

Annotation Processor at Runtime


[2]
public class NotNullProcessor {
public void validate(Object obj) throws Exception {
Class clazz = obj.getClass();
Field[] fields = clazz.getDeclaredFields();
for(Field field : fields) {
field.setAccessible(true);
Annotation annotation =
field.getAnnotation(NotNull.class);
if(annotation!=null) {
Object objValue = field.get(obj);
if(objValue==null) {
throw new RuntimeException("Attribute
'"+field.getName()+"' cannot be null.");
}
}
}
}

Annotation Processor at Runtime


[3]
public class NotNullProcessorTest {
public static void main(String[] args) throws Exception {
MyEntity e1 = new MyEntity();
e1.name = "Daniel";
MyEntity e2 = new MyEntity();
e2.name = null;
NotNullProcessor nnp = new NotNullProcessor();
nnp.validate(e1);
System.out.println("Object e1 valid.");
nnp.validate(e2);
}
}

Annotation Processor at Runtime


[4]
Object e1 valid.
Exception in thread "main"
java.lang.RuntimeException: Attribute 'name'
cannot be null.
at
com.djph.annotation.rtprocessor.NotNullProcesso
r.validate(NotNullProcessor.java:20)
at
com.djph.annotation.rtprocessor.NotNullProcesso
rTest.main(NotNullProcessorTest.java:18)

Annotation Processing Tool


(apt)

The apt tool is a command-line utility for


annotation processing.
It includes a set of reflective APIs and
supporting infrastructure to process program
annotations (JSR 175).
The apt tool first runs annotation processors
that can produce new source code and other
files.
JSR 269 support (JDK 6), javac now acts
analogously to the apt command in JDK 5.
The apt tool and its associated API contained
in the package com.sun.mirror have been
deprecated since Java SE 7.

Create Annotation
Preprocessor
@SupportedAnnotationTypes({"*"})
@SupportedSourceVersion(SourceVersion.RELEAS
E_7)
public class SimpleProcessor extends
AbstractProcessor
{
@Override
public boolean process(Set<? extends
TypeElement> annotations, RoundEnvironment
roundEnv)
{
return false;
}
}

Create Annotation Preprocessor


(Note)
Set<? extends Element> elements =
roundEnv.getElementsAnnotatedWith(MyAnnotation.class);
TypeElement te = (TypeElement) element;
PackageElement pe = (PackageElement)
te.getEnclosingElement();
String packageLocation = pe.getQualifiedName().toString();
String sourceFile = te.getQualifiedName().toString()+'_';
Filer filer = processingEnv.getFiler();
JavaFileObject javaFileObject = filer.createSourceFile(sourceFile);
Writer writer = javaFileObject.openWriter();
processingEnv.getMessager().printMessage(Diagnostic.Kind.NOT
E, "Processing annotation done.");

Use for??? [1]


Create custom javadoc.
Create web service document.

Use for??? [2]


public class Employee {
private Double salary;
{...Setter...} {...Getter...}
}
Criteria cr = session.createCriteria(Employee.class);
cr.add(Restrictions.eq("salary", 2000));
List results = cr.list();

public class Employee_ {


public static final String salary = "salary";
}
Criteria cr = session.createCriteria(Employee.class);
cr.add(Restrictions.eq(Employee_.salary, 2000));
List results = cr.list();

Only that???
Context context = ((JavacProcessingEnvironment)
processingEnv).getContext();
TreeMaker treeMaker = TreeMaker.instance(context);
JavacElements elementUtils = (JavacElements)
processingEnv.getElementUtils();
JCTree.JCClassDecl classDecl = (JCTree.JCClassDecl)
elementUtils.getTree(element);

How javac work after JDK


1.5???

AST

Modify AST Example


methodDecl.body = treeMaker.Block(0, List.of(
treeMaker.Exec(
treeMaker.Apply(
List.<JCTree.JCExpression>nil(),
treeMaker.Select(
treeMaker.Select(
treeMaker.Ident(elementUtils.getName("System")),
elementUtils.getName("out")
),
elementUtils.getName("println")
),
List.<JCTree.JCExpression>of(
treeMaker.Literal("Hello, world!!!")
)
)
),
methodDecl.body
));

How to run???
Using apt processor (JDK 1.5)
Using javac processor (JDK 1.6)
Create file
javax.annotation.processing.Processo
r that contains all processor class,
separate by new line at folder METAINF.services

Project Lombok
Project Lombok is annotation
processor compiler plugin for javac
that provides a handful of very
focused annotations for your classes
to generate you highly optimized
implementations of some of the most
common boilerplate code that Java
developer needs.
Created by Reinier Zwitserloot & Roel
Spilker.

How Project Lombok work???

Use for?
@Data
public class Person {
private String name;
public static void main(String[] args) {
Person p = new Person();
p.setName("Daniel");
System.out.println("Name:
"+p.getName());
}
}

Project Lombok Annotation


@Data
@Getter / @Setter
@ToString
@val
@Log

Trick or Hack???
The annotation processing spec
doesn't allow you to modify existing
classes.
The annotation processing API doesn't
provide a mechanism for changing the
AST of a class.

Disadvantages
Debug
WYSIWYG
Time Bomb

Thank You

You might also like