Solo  当前访客:0 登录 注册

Java注解的玩儿法。

2018-08-01 17:02:19 imadiaos
2  评论    2,315  浏览

元注解是指注解的注解,包括@Retention @Target @Document @Inherited四种。

呃,看了一眼源码其实8(我截止到今天用的是8,2018/8/1)里面还有 @Repeatable。
WX201808011513532xpng

先按顺序来分析:

1、@Retention作用

定义注解的保留策略

  • @Retention(RetentionPolicy.SOURCE): 注解仅保存在源码阶段,编译和运行时都不会有。
/**
 * Annotations are to be discarded by the compiler. 
 */
 SOURCE,
  • @Retention(RetentionPolicy.CLASS): 注解会在class字节码中存在,运行时不可见。此策略为默认。
/**
 * Annotations are to be recorded in the class file by the compiler 
 * but need not be retained by the VM at run time.  This is the default 
 * behavior. 
 */
 CLASS,
  • @Retention(RetentionPolicy.RUNTIME): 注解会在class字节码文件中存在,在运行时可以通过反射获取到
/**
 * Annotations are to be recorded in the class file by the compiler and 
 * retained by the VM at run time, so they may be read reflectively. 
 * 
 * @see java.lang.reflect.AnnotatedElement
 */
 RUNTIME

2、@Target: 定义注解的作用目标

public enum ElementType {
    /** Class, interface (including annotation type), or enum declaration */
  TYPE,  // 类,接口,枚举,注解。

    /** Field declaration (includes enum constants) */
  FIELD, // 字段, 枚举常量。

    /** Method declaration */
  METHOD, // 方法

    /** Formal parameter declaration */
  PARAMETER, // 方法参数

    /** Constructor declaration */
  CONSTRUCTOR, // 构造函数

    /** Local variable declaration */
  LOCAL_VARIABLE, // 局部变量

    /** Annotation type declaration */
  ANNOTATION_TYPE, // 注解

    /** Package declaration */
  PACKAGE, // 包

    /**
	 * Type parameter declaration 
	 * 
	 * @since 1.8
	 */  
 TYPE_PARAMETER, // 新特性,表示这个 Annotation 可以用在 Type 的声明式前

    /**
	 * Use of a type * * @since 1.8
	 */  
 TYPE_USE // 新特性,表示当前Annotation 可以用在所有使用 Type 的地方(如:泛型,类型转换等)。
}

3、@Documented

表示可以出现在javadoc中,

4、@Inherited

该注解表示子类可以集成加载父类上的注解。但要注意:

 1.注解定义在类上面,子类是可以继承该注解的。

 2.注解定义在方法上面,子类也可以继承该注解,但是如果子类复写了父类中定义了注解的方法,那么子类将无法继承该方法的注解,也就是说,子类在复写父类中被@Inherited标注的方法时,会将该方法上面的注解覆盖掉

 3.Interface的实现类(implements实现)无法继承接口中所定义的被@Inherited标注的注解

@Inherited的总结来自:
CShawnX:Java和Android中的注解

5、@Repeatable 可以重复注解

在之前,相同的注解在同一个位置只能使用一次, java8 引入了重复注解机制。可以让一个注解在一个位置引用多次。例如:

@interface Persons { 
    Person[] value(); 
}

@Repeatable(Persons.class)
@interface Person{ 
    String role default""; 
}

@Person(role="artist")
@Person(role="coder")
@Person(role="PM")
public class SuperMan{ 

}

表示这个SuperMan 可以是三种角色,artist,coder,PM。

上面代码中,用@Repeatable注解了注解Person,而其括号内的Persons.class表示为一个注解容器。
按照规定,它里面必须要有一个 value 的属性,属性类型是一个被 @Repeatable 注解过的注解数组,注意它是数组。

注解怎么玩儿?

注解是一系列元数据,它提供数据用来解释程序代码,但是注解并非是所解释的代码本身的一部分。注解对于代码的运行效果没有直接影响。

注解有许多用处,主要如下:

  • 提供信息给编译器: 编译器可以利用注解来探测错误和警告信息
  • 编译阶段时的处理: 软件工具可以用来利用注解信息来生成代码、Html文档或者做其它相应处理。
  • 运行时的处理: 某些注解可以在程序运行的时候接受代码的提取

玩儿法一

java预置了一些注解,可以通过这些注解,对代码进行描述。达到某种目的。
@Deprecated、@Override、@SuppressWarnings、@SafeVarargs、@FunctionalInterface

玩儿法二

那就是自己定义一些注解了。
通过反射,获得相关的注解,并未目标增加一系列附加的处理操作。因为正像官方描述:注解对于代码的运行效果没有直接影响。但是我们可以为其增强啊。
getAnnotation()或者getAnnotations()可以获得目标的注解对象或者所有注解的数组。再根据这些注解对象以及其成员属性。
可以据此为其编写外部能力。

应用场景

日志、测试类、Ioc、功能增强等。

,
wenandlu
回复»  |  2018-08-02 09:41:13

以前玩过,根据实体类注解,生成列表的excel导出文件,还是比较实用的,也不会破坏代码结构,所以提醒一下,有个RUNTIME注解很重要,我曾在这里耗费过半天时间,就是没有加入RUNTIME注解,导致获取不到注解

JFLB0907
回复»  |  2018-08-02 09:32:11

都是大神:joy:

发表评论

validate
TOP