Java Advanced Features-annotations, this is perhaps the most simple and understandable article

Source: Internet
Author: User

Bloggers in the beginning of the comments when the introduction of the online most are directly introduced to the use or function, no actual application scenarios, length and long lead to learning difficult to understand its intentions, and learn to forget Qaq. In this article, I will use the actual application scenario as far as possible, the gentle introduction of Java annotations.

Java annotations are jdk1.5 after the new features, for its application is very broad, we first look at the application of annotations, Baidu Encyclopedia said:

As we can see, the role of annotations has three aspects:

Write Doc documents: This is a very common @return and @author, add these annotations, we can use the JDK to help us automatically generate the corresponding API documentation

Compile check: This is also very common @Override, and the function is very powerful, I will be in a future article to introduce

Code Analysis: This is the focus of this article. This is as much a powerful feature as a compile check, but there are some performance problems with the compilation check because it uses reflection.

In the background development of SSH three framework, and we Android Retrofit,butterknife,lombok and other frameworks and plugins are also a lot of use of annotations. Here I will be a fake butterknife by hand to illustrate the use of annotations, how to use.

Let's first look at the snippet code

public class MainActivity extends AppCompatActivity {@OnClick(R.id.test_btn)void test(){    test_tv.setText("恭喜您,绑定成功了!");}@FindViewByID(R.id.test_tv)TextView test_tv;@Overrideprotected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_main);    ButterKnife.bindView(this);}}

This is one of the most basic activity, with 2 controls, button and TextView

The TextView text is changed after I click the button. And what I did was just Butterknife.bindview (this) and add 2 annotations, so that the control is bound, eliminating a lot of business-independent code, is not much more concise.

Read the function of the annotation is not very want to understand how it is done, next I will see what it is, how to use, how to use

What are annotations

Officials call it metadata, a data that describes the data. So, it can be said that the annotation is the source code metadata. It can be used to describe and tag our source code.

How to define an annotation

Here's a @OnClick note that I've defined above

@Target(ElementType.METHOD)@Retention(RetentionPolicy.RUNTIME)public @interface OnClick {int value() default 0;}
As you can see and define a class, just change the class to @interface, and at the top there are several original annotations that illustrate some important information about this annotation, as follows:

The j2se5.0 version provides four types of meta-annotations in java.lang.annotation, specifically annotated with other annotations:

@Documented – whether the annotations will be included in the Javadoc
@Retention – When to use this annotation
@Target? – Where the annotations are used
@Inherited – whether subclasses are allowed to inherit the annotation

@Documented – a simple annotations tag annotation that indicates whether to add annotation information to a Java document, usually without a tube.

@Retention – Defining the life cycle of this annotation is important and must be specified, the following is an introduction to 3 life cycles

RetentionPolicy.SOURCE – 在编译阶段丢弃。这些注解在编译结束之后就不再有任何意义,所以它们不会写入字节码。@Override, @SuppressWarnings都属于这类注解。RetentionPolicy.CLASS – 在类加载的时候丢弃。在字节码文件的处理中有用。注解默认使用这种方式。RetentionPolicy.RUNTIME– 始终不会丢弃,运行期也保留该注解,因此可以使用反射机制读取该注解的信息。我们自定义的注解通常使用这种方式。

@Target – Indicates where the note is used. If not explicitly stated, the annotations can be placed anywhere. The following are some of the available parameters. Note that the attribute annotations are compatible, and if you want to add annotations to all 7 attributes, just exclude an attribute, then you need to define the target to include all the attributes.

ElementType.TYPE:用于描述类、接口或enum声明ElementType.FIELD:用于描述实例变量ElementType.METHODElementType.PARAMETERElementType.CONSTRUCTORElementType.LOCAL_VARIABLEElementType.ANNOTATION_TYPE 另一个注释ElementType.PACKAGE 用于记录java文件的package信息

@Inherited – Define the relationship of this comment and subclass

So what is the definition of the content in the annotation body?

Annotations only supports basic types, string, and enumeration types. All attributes in the note are defined as methods and allow default values to be provided.

@Target(ElementType.METHOD)@Retention(RetentionPolicy.RUNTIME)@interface Book{public enum Priority {LOW, MEDIUM, HIGH}String author() default "Yash";int price() default 20;Status status() default Status.NOT_STARTED;}

See how it's used.

@Todo(priority = Todo.Priority.MEDIUM, author = "zsq", status = Todo.Status.STARTED)public void incompleteMethod1() {}

Assigns a value to a field in the form of field name =, and if not assigned, the default value is used. If there is only one attribute in the annotation, you can name it directly as "value", without having to label the property name, such as the @OnClick annotation I defined.

Well, it takes a lot of energy to get to know him, and it's time to see how we can use it.

We define our own annotations and apply them to the methods of business logic. Now we need to write a user program that calls our annotations. Here we need to use the reflection mechanism. If you are familiar with reflection code, you know that reflection can provide class names, methods, and instance variable objects. All of these objects have getannotation () This method is used to return the annotation information. We need to convert this object to our custom annotations (after using the instanceof () check), and we can invoke the method inside the custom comment.

All of these objects have getannotation ()! All of these objects have getannotation ()! All of these objects have getannotation ()!

Important API say 3 times, another use of several methods is also very important, the following code will demonstrate, more API use reference can go to consult the JDK document.

Specifically to our example of this article, call the annotated guy is the butterknife we just used in the mainactivity, we set the listening annotations to see what it did

public static final void bindView(final Activity activity){    traversalMethod(activity);    traversalField(activity);}

In the Butterknife.bindview we call (this) we get an instance of mainactivity and iterate through all the methods inside it:

private static void traversalMethod(final Activity activity) {    Method[] methodArray = getObjectMethodArray(activity);    for (final Method method:methodArray){        if(isAnnotationPresent(method)){            int viewID = getViewID(method);            setOnClickListenerForControl(activity, method, viewID);        }    }}private static Method[] getObjectMethodArray(Activity activity) {    return activity.getClass().getMethods();}

Then judge whether the method is annotated by us:

private static boolean isAnnotationPresent(Method method) {    return method.isAnnotationPresent(OnClick.class);}

If we annotate with annotations, we get the space ID saved in the annotations through annotations, and we use the Mainactivity instance to set the click Listener for it, and invoke the method of annotation annotation within the listener.

private static int getViewID(Method method) {    return method.getAnnotation(OnClick.class).value();}private static void setOnClickListenerForControl(final Activity activity, final Method method, int viewID) {    activity.findViewById(viewID).setOnClickListener(new View.OnClickListener() {        @Override        public void onClick(View view) {            try {                method.invoke(activity);            } catch (IllegalAccessException e) {                e.printStackTrace();            } catch (InvocationTargetException e) {                e.printStackTrace();            }        }    });}
Done! Isn't it simple?

We realize the function of Butterknife by using reflection to get annotations, but the article begins with the lack of reflection performance. In fact, Butterknife itself is not a reflection, but the use of apt tools at compile time can get all the methods, fields, and their annotations, thus avoiding the use of reflection, solve the problem of performance. The next article I will explain the 3rd in this article, that is, butterknife actual use of the method, our own butterknife to butterknife the official implementation method.

The following GitHub address is the demo used in this article:
Https://github.com/sally519/MyButterKnief

The article is very long, hope to see the people can harvest something the author level is limited, if there are omissions and errors, welcome correction!

Java Advanced Features-annotations, this is perhaps the most simple and understandable article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.