美文网首页
Java 注解(Annotation)

Java 注解(Annotation)

作者: Jason_cyj | 来源:发表于2018-06-24 22:47 被阅读15次

一 什么是注解?

Annontation是Java5开始引入的新特征,中文翻译为注解,注解可以理解为描述数据自身的数据。即注解就是代码的元数据,他们包含了代码自身的信息。注解可以作用在包,类,方法,变量以及参数上。

二 注解基本使用

2.1 注解的声明

可以通过以下方式声明一个注解:

//声明一个Test注解
@Target(ElementType. TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface TestAnnotation{

} 

这样,就声明了一个TestAnnotation注解,然后该注解怎么使用呢?

2.2 注解的使用

上面创建了一个注解,那么注解的的使用方法是什么呢。

@TestAnnotation
public class TestClass {
}

创建一个类 TestClass,然后在类定义的地方加上 @TestAnnotation 就可以用 TestAnnotation 注解这个类了。
虽然通过上述声明,就可以使用,但要想理解注解的更详细的工作,还需要介绍一下元注解。

2.3 元注解

元注解是可以注解到注解上的注解,或者说元注解是一种基本注解,但是它能够应用到其它的注解上面,元标签有: @Target、@Retention、@Documented、@Inherited、@Repeatable 5 种,下面分别介绍。

2.3.1 @Target

@Target是用来约束注解可以应用的地方(如方法、类或字段等),其中ElementType是枚举类型,可以的取值有:

ElementType 值 含义
ElementType. TYPE 用于类、接口(包括注解类型)、枚举
ElementType. FIELD 用于字段(域)声明
ElementType. METHOD 用于方法声明
ElementType. PARAMETER 用于参数声明
ElementType. CONSTRUCTOR 用于构造函数声明
ElementType. LOCAL_VARIABLE 用于局部变量声明
ElementType.ANNOTATION_TYPE 用于注解声明(即应用于另一个注解上)
ElementType. PACKAGE 用于包声明
ElementType. TYPE_PARAMETER 用于类型参数声明(1.8新加入)
ElementType. TYPE_USE 类型使用声明(1.8新加入)
2.3.2 @Retention

@Retention用来约束注解的生命周期,分别有三个值,源码级别(source),类文件级别(class)或者运行时级别(runtime),其含有如下:

RetentionPolicy 值 含义
RetentionPolicy.SOURCE 注解只在源码阶段保留,在编译器进行编译时它将被丢弃忽视
RetentionPolicy.CLASS 注解在class文件中可用,它并不会被加载到 JVM 中
RetentionPolicy.RUNTIME 注解可以保留到程序运行的时候,它会被加载进入到 JVM 中。
2.3.3 @Documented

@Documented作用是能够将注解中的元素包含到 Javadoc 中去

2.3.4 @Inherited

@Inherited可以让注解被继承,但这并不是真的继承,只是通过使用@Inherited,可以让子类Class对象使用getAnnotations()获取父类被@Inherited修饰的注解

2.3.5 @ Repeatable

@Repeatable 是 Java 1.8 才加进来的,它表示在同一个位置重复相同的注解。

三 Java内置的注解

Java提供的内置注解,常见的主要有3个,如下:

3.1 @Deprecated

用于标明已经过时的方法或类,这个在编码时经常会碰到的,主要是告诉开发者正在调用一个过时的元素比如过时的方法、过时的类、过时的成员变量。源码如下:

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE})
public @interface Deprecated {
}
3.2 @Override

@Override用于标明此方法覆盖了父类的方法,也是大家很熟悉了的一个注解,源码如下:

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}
3.3 @ SuppressWarnnings

@ SuppressWarnnings用于有选择的关闭编译器对类、方法、成员变量、变量初始化的警告,也是大家很熟悉了的一个注解,源码如下:

@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
@Retention(RetentionPolicy.SOURCE)
public @interface SuppressWarnings {
    String[] value();
}

四 自定义注解实例

声明一个自定义注解:
//类注解

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface TestClassAnno {
    public int id() default -1;
    public String message() default "test";
}
//域注解
@Target(FIELD)
@Retention(RUNTIME)
@Documented
 public @interface TestFieldAnno {
     String value() default "";
}

编写一个注解处理器类 AnnotationDemo 就可以测试上述的自定义注解。

@TestClassAnno(id=1,message="类注解测试")
public class AnnotationDemo{
    @TestFieldAnno(value="域注解测试")
    String name;
    public static void main(String[] args){
        boolean hasAnnotation = AnnotationDemo.class.isAnnotationPresent(TestClassAnno.class);
        if ( hasAnnotation ) {
            TestClassAnno testAnnotation = AnnotationDemo.class.getAnnotation(TestClassAnno.class);
            System.out.println("id:"+testAnnotation.id());
            System.out.println("msg:"+testAnnotation.msg());
        }
     try {
            Field name = AnnotationDemo.class.getDeclaredField("name");
            name.setAccessible(true);
            //获取一个成员变量上的注解
            TestFieldAnno testFieldAnno = AnnotationDemo.class.getAnnotation(TestFieldAnno.class);
            if ( testFieldAnno != null ) {
                System.out.println("testFieldAnno name:"+testFieldAnno.name());
            }

        }catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            System.out.println(e.getMessage());
        }
  }

}

五注解的知名类库

Java中一些类库:JAXB, Spring Framework, Findbugs, Log4j, Hibernate, JUnit等
Android中的一些类库:ButterKnife、Dagger2、Retrofit等。

相关文章

网友评论

      本文标题:Java 注解(Annotation)

      本文链接:https://www.haomeiwen.com/subject/eyysyftx.html