原文地址:https://dzone.com/articles/how-annotations-work-java

Annotations have been a very important part of Java and it’s been there from the time of J2SE 5.0. All of us might have seen annotations like @Override and @Deprecated in our application code at some place or another. In this article I will discuss what exactly annotations are, why they were introduced, how they work, how to write custom annotations (with example code), what could be valid scenarios for annotations and lastly Annotations and ADF. It’s going to be a long post, so get a mug of coffee and get ready to dive into world of annotations.

What are Annotations?

One word to explain Annotation is Metadata. Metadata is data about data. So Annotations are metadata for code. For example look at following piece of code.

@Override

public String toString() {

return "This is String Representation of current object.";

}

I have overridden the toString() method and used @Override annotation in above code. Even if I don’t put @Override, code works properly without any issue. So what’s the advantage and what does this annotation stand for? @Override tells the compiler that this method is an overridden method (metadata about method) and if any such method does not exist in parent class, then throw a compiler error (method does not override a method from its super class). Now if I would have made a typography mistake and used method name as toStrring() {double r} and if I wouldn’t have used @Override, my code would have compiled and executed successfully but outcome would be different from what I would have accepted. So now we understand what annotations are but still it’s good to read formal definitions

Annotation is special kind of Java construct used to decorate a class, method, field, parameter, variable, constructor, or package. It’s the vehicle chosen by JSR-175 to provide metadata.

Why Were Annotations Introduced?

Prior to annotation (and even after) XML were extensively used for metadata and somehow a particular set of Application Developers and Architects thought XML maintenance was getting troublesome. They wanted something which could be coupled closely with code instead of XML which is very loosely coupled (in some cases almost separate) from code. If you google “XML vs. annotations”, you will find a lot of interesting debates. Interesting point is XML configurations were introduced to separate configuration from code. Last two statements might create a doubt in your mind that these two are creating a cycle, but both have their pros and cons. Let’s try to understand with an example.

Suppose, you want to set some application wide constants/parameters. In this scenario, XML would be a better choice because this is not related with any specific piece of code. If you want to expose some method as a service, annotation would be a better choice as it needs to be tightly coupled with that method and developer of the method must be aware of this.

Another important factor is that annotation defines a standard way of defining metadata in code. Prior to annotations people also used their own ways to define metadata. Some examples are – using marker interfaces, comments, transient keywords etc. Each developer decided his own way to decide metadata, but annotation standardized things.

These days most frameworks use combination of both XML and Annotations to leverage positive aspects of both.

How Annotations Work and How to Write Custom Annotations

Before I start this explanation, I will suggest you download this sample code for annotations (AnnotationsSample.zip) and keep that open in any IDE of your choice, as it will help you to understand following explanation better.

Writing annotations is very simple. You can compare annotation definition to an interface definition. Let’s have a look at two examples – One is standard @Override annotation and second is a custom annotation @Todo

@Target(ElementType.METHOD)

@Retention(RetentionPolicy.SOURCE)

public @interface Override {

}

Something seems fishy about @Override, it’s not doing anything, how it checks if a method is defined in parent class. Well, don’t be surprised, I am not kidding you. Override annotation’s definition has that much code only. This is the most important part to understand and I am reiterating myself – Annotations are only metadata and they do not contain any business logic. Tough to digest but true. If annotations do not contain the logic than someone else must be doing something and that someone is consumer of this annotation metadata. Annotations only provide some information about the attribute (class/method/package/field) on which it is defined. Consumer is a piece of code which reads this information and then performs necessary logic.

When we are talking about standard annotations like @Override – JVM is the consumer and it works at bytecode level. Now that’s something application developers can’t control and can’t use for custom annotations. So we need to write consumers for our annotations by ourselves.

Let’s understand the key terms used for writing annotations one by one. In the above examples, you will see annotations are used on annotations.

J2SE 5.0 provides four annotations in the java.lang.annotation package that are used only when writing annotations:

@Documented – Whether to put the annotation in Javadocs

@Retention – When the annotation is needed

@Target? – Places the annotation can go

@Inherited – Whether subclasses get the annotation.

@Documented – A simple market annotations which tells whether to add Annotation in java doc or not.

@Retention – Defines for how long the annotation should be kept.

RetentionPolicy.SOURCE – Discard during the compile. These annotations don’t make any sense after the compile has completed, so they aren’t written to the bytecode. Examples @Override, @SuppressWarnings
RetentionPolicy.CLASS – Discard during class load. Useful when doing bytecode-level post-processing. Somewhat surprisingly, this is the default.
RetentionPolicy.RUNTIME – Do not discard. The annotation should be available for reflection at runtime. This is what we generally use for our custom annotations.

@Target – Where annotation can be placed. If you don’t specify this, annotation can be placed anywhere. Following are the valid values. One important point here is, it’s inclusive only which means if you want annotation on 7 attributes and just want to exclude only one attribute, you need to include all 7 while defining target.

ElementType.TYPE (class, interface, enum)

ElementType.FIELD (instance variable)

ElementType.METHOD

ElementType.PARAMETER

ElementType.CONSTRUCTOR

ElementType.LOCAL_VARIABLE

ElementType.ANNOTATION_TYPE (on another annotation)

ElementType.PACKAGE (remember package-info.java)

@Inherited – Controls whether annotation should affect subclass.

Now what goes inside an annotation definition? Annotations only support primitives, string and enumerations. All attributes of annotations are defined as methods and default values can also be provided

@Target(ElementType.METHOD)

@Retention(RetentionPolicy.RUNTIME)

@interface Todo {

public enum Priority {LOW, MEDIUM, HIGH}

public enum Status {STARTED, NOT_STARTED}

String author() default "Yash";

Priority priority() default Priority.LOW;

Status status() default Status.NOT_STARTED;

}

Following is an example of how the above annotation can be used

@Todo(priority = Todo.Priority.MEDIUM, author = "Yashwant", status = Todo.Status.STARTED)

public void incompleteMethod1() {

//Some business logic is written

//But it’s not complete yet

}

If we have only one attribute inside an annotation, it should be named “value” and can be used without attribute name while using it.

@interface Author{

String value();

}

@Author("Yashwant")

public void someMethod() {

}

So far so good. We have defined our custom annotation and applied it to some business logic methods. Now it’s time to write a consumer. For that we will need to use Reflection. If you are familiar with Reflection code, you know reflection provides Class, Method and Field objects. All of these have a getAnnotation() method which returns the annotation object. We need to cast this object as our custom annotation (after checking with instanceOf()) and then we can call methods defined in our custom annotation. Let’s look at the sample code, which uses above annotation:

Class businessLogicClass = BusinessLogic.class;

for(Method method : businessLogicClass.getMethods()) {

Todo todoAnnotation = (Todo)method.getAnnotation(Todo.class);

if(todoAnnotation != null) {

System.out.println(" Method Name : " + method.getName());

System.out.println(" Author : " + todoAnnotation.author());

System.out.println(" Priority : " + todoAnnotation.priority());

System.out.println(" Status : " + todoAnnotation.status());

}

}

Use Cases for Annotations

Annotations are very powerful and Frameworks like spring and Hibernate use Annotations very extensively for logging and validations. Annotations can be used in places where marker interfaces are used. Marker interfaces are for the complete class but you can define annotation which could be used on individual methods for example whether a certain method is exposed as service method or not.

In latest servlet specification 3.0 a lot of new Annotations are introduced, especially related with servlet security.

HandlesTypes – This annotation is used to declare an array of application classes which are passed to a ServletContainerInitializer.

HttpConstraint – This annotation represents the security constraints that are applied to all requests with HTTP protocol method types that are not otherwise represented by a corresponding HttpMethodConstraint in a ServletSecurity annotation.

HttpMethodConstraint – Specific security constraints can be applied to different types of request, differentiated by the HTTP protocol method type by using this annotation inside the ServletSecurity annotation.

MultipartConfig – This annotation is used to indicate that the Servlet on which it is declared expects requests to made using the multipart/form-data MIME type.

ServletSecurity – Declare this annotation on a Servlet implementation class to enforce security constraints on HTTP protocol requests.

WebFilter – The annotation used to declare a Servlet Filter.

WebInitParam – The annotation used to declare an initialization parameter on a Servlet or Filter, within a WebFilter or WebServlet annotation.

WebListener -The annotation used to declare a listener for various types of event, in a given web application context.
WebServlet – This annotation is used to declare the configuration of an Servlet.

ADF (Application Development Framework) and Annotations

Now we are at the last part of our discussion. Application Development Framework, also known as ADF, is developed by Oracle and used to build Oracle Fusion Application. We have seen pros and cons, we know how to write custom annotations but where to use custom annotations in ADF? Does ADF provide any native Annotations? Interesting questions, but there are certain limitations that prevent usage of annotation to a large scale in ADF. Frameworks which are mentioned earlier like spring and Hibernate, use AOP (Aspect oriented programming). In AOP, framework provides mechanism to inject code for preProcessing and postProcessing for any event. For example, you have a hook to place code before and after a method execution, so you can write your consumer code in those places. ADF does not use AOP. If we have any valid use case for annotations, we might need to go via inheritance way.

Hope you enjoyed this article. Please drop in your comments.

Source : How Annotations Work In Java

转载于:https://www.cnblogs.com/davidwang456/p/5564082.html

How Do Annotations Work in Java?--转相关推荐

  1. Java中的注解 Annotations

    Java Annotations Java Annotations提供有关代码的信息.Java注释对它们注释的代码没有直接影响.在java annotations教程中,我们将研究以下内容: 内置Ja ...

  2. Processing Java Annotations Using Reflection

    (转载)https://keyholesoftware.com/2014/09/15/java-annotations-using-reflection/ In my previous article ...

  3. Appium的Java封装

    文章出处 http://blog.csdn.net/niubitianping/article/details/52612211 一.为什么需要封装? 封装的本意就是为了方便.简洁. 二.Androi ...

  4. 【译】Core Java Questions and Answers【1-33】

    前言 译文链接:http://www.journaldev.com/2366/core-java-interview-questions-and-answers Java 8有哪些重要的特性 Java ...

  5. 接口自动化框架(java)--2.接口用例POST请求,参数配置

    这套框架的报告是自己封装的 Post类型的接口通常有请求参数,请求参数也是json类型,所以需要写一个类将请求参数序列化成json对象 以常见的登录接口为例 新建一个package,和postPara ...

  6. java学习笔记(12) —— Struts2 通过 xml /json 实现简单的业务处理

    XML 1.引入dom4j-2.0.0.jar 2.引入jquery-1.8.2.js 3.新建common.js getInfo = function(){$.post("getXmlAc ...

  7. Selenium+java - 借助autolt完成上传文件操作

    写在前面: 上传文件是每个自动化测试同学会遇到,而且可以说是面试必考的问题,标准控件我们一般用sendkeys()就能完成上传,但是我们的测试网站的上传控件一般为自己封装的,用传统的上传已经不好用了, ...

  8. java sqlite mybatis_Spring boot + Mybatis + SQLite 搭建blog API

    Spring boot + Mybatis + SQLite 搭建blog API 一.准备环境 二.创建一个SpringBoot项目 在此我就不再演示如何创建SpringBoot项目了,需要的请看[ ...

  9. How do annotations work internally--转

    原文地址:http://stackoverflow.com/questions/18189980/how-do-annotations-work-internally The first main d ...

最新文章

  1. IT人的学习方法论-4 一些重要的能力
  2. proxy in nodejs code
  3. 算法基础:常用的查找算法知识笔记
  4. 演练 宠物店挑小动物 java 1615136001
  5. php中英文版切换最好的办法,php做项目进行中英文的切换,如何快速实现
  6. R/3 ABAP开发学习笔记---网摘
  7. 微服务下flask和celery的通信
  8. 一次完整的软件工程课程设计
  9. 一文掌握SQLite3基本用法
  10. OpenFOAM-6.0 如何创建已有标量场的梯度向量场
  11. 火遍全网的「蚂蚁呀嘿」教程开源了!
  12. 代码审计--25--RIPS详细
  13. 新手必看的模具设计十大分模法,干货满满!!!
  14. 爱航拍,可以在这里晒出无人机和航拍故事
  15. Ubuntu18.04下安装git记录
  16. [转]git图解(3):分支操作
  17. 虚拟机扩容、删除多余分区分配到C盘
  18. 3D数学 方向、方位和角位移
  19. 软件系统六大设计原则
  20. python自学篇十六[pandas——数据分析 (二):读取文件+索引+NaNs处理方法]

热门文章

  1. mybatis返回map键值对_mybatis返回map结果集怎么配置
  2. Shell中的分支语句
  3. Qt中的QColorDialog
  4. include的两种形式、CPP的搜索路径
  5. python读取txt为dataframe_python批量读取txt文件为DataFrame的方法
  6. web项目打包到上线教程_手把手教你在 IntelliJ IDEA 中部署 Web 项目
  7. html显示后台传来的byte类型的数据_java的数据类型
  8. 树莓派:linux库概念及相关编程(面试重点):以及USB端口号找到不的情况
  9. YOLOv5-LibTorch
  10. ROW_NUMBER() OVER (PARTITION BY 字段1 ORDER BY 字段2 DESC)