FKJAVA读书笔记--第十四章--Annotation

1.基本的Annotation

a) @Override:限定重写父类的方法(只能用于方法,不能用于其他元素)

b) @Deprecated:标示已经过时

c) @SurpressWarnings:抑制编译器警告: @SuppressWarnings("unused")

d) @SafeVarargs:泛型擦除时,当把一个不带泛型的对象赋给一个带泛型的变量时,往往就会发生“堆污染”

 List list=new ArrayList<>();

 list.add(20);

 List<String> list2=list;

 System.out.println(list2.get(0));//运行时程序会报错,发生类型转换异常

 

2.JDK的元Annotation:元Annotation用于修饰其他的Annotation定义

a) 使用@Retention:用于修饰指定的Annotation可以保留多长时间

i. RetentionPolicy值:

1. RetentionPolicy.CLASS:默认值,编译器把Annotation记录在class文件中。当运行java程序时,JVM不再保留Annotation

2. RetentionPolicy.RUNTIME:编译器把Annotation记录在class文件中,当运行java程序时,JVM保留Annotation

//保留到运行时

@Retention(value=RetentionPolicy.RUNTIME)

public @interface RetentionTest{}

3. RetentionPolicy.SOURCEAnnotation只留在源代码中,编译器直接丢弃这种Annotation

//将被编译器直接丢弃

@Retention(RetentionPolicy.SOURCE)

public @interface RetentionTest{}

ii. 如果Annotation中只有一个value成员变量,那么使用该Annotation时可以直接在其后面的括号里指定成员value的值,无须使用name=value的形式。

b) 使用@Target:用于指定被修饰的Annotation只能修饰哪些程序单元。

i. ElementType值:

1. ElementType.ANNOTATION_TYPE:用于指定该策略的Annotation只能修饰Annotation

2. ElementType.CONSTRUCTOR:用于指定该策略的Annotation只能修饰构造器;

3. ElementType.FIELD:用于指定该策略的Annotation只能修饰成员变量;

4. ElementType.LOCAL_VARIABLE:指定策略的Annotation只能修饰局部变量;

5. ElementType.METHOD:用于指定该策略的Annotation只能修饰方法定义;

6. ElementType.PACKAGE:用于指定该策略的Annotation只能修饰包定义;

7. ElementType.PARAMETER:用于指定该策略的Annotation只能修饰参数;

8. ElementType.TYPE:指定该策略Annotation可以修饰类、接口、或者枚举定义。

 

@Target(ElementType.METHOD)

public @interface RetentionTest{}

c) 使用Documented:用于指定该元Annotation修饰的Annotation类将被javadoc工具提取成文档。

@Documented

public @interface RetentionTest{}

d) 使用@Inherited:指定被他修饰的Annotation将具有继承性---如果某个类使用了@A Annotation(定义该Annotation时使用了@Inherited修饰)修饰,则其子类将会自动被@A修饰;

可以用:XXX.class.isAnnotationPresent(A.class) 来判断一个类是否有RetentionTest的修饰。

 

 

3.使用自定义的Annotation:

a) 定义Annotation:使用 @interface 关键字:

public @interface Mytag

b) 定义Annotation成员变量:以无形参的方法形式来声明,其方法和返回值定义了该成员变量的名字和类型:

{

   String name();

   int age();

}

@Mytag(name="ss",age=3)//使用带成员变量的Annotation时需要为成员变量赋值

public void info(){}

c) 也可以为Annotation的成员变量指定默认值,这样在使用时,如果不为成员变量指定值,则使用默认值

{

    String name() default "ss";

    int age() default 2;

}

d) 根据Annotation是否含有成员变量把其分为两类:

i. 标记Annotation:一个没有定义成员变量的Annotation类型被称为标记,这种Annotation仅利用自身的存在与否来为我们提供信息,比如@Override

ii. 元数据Annotation:包含成员比那里的Annotation,因为他们可以接受更多的元数据,所以也被称为元数据Annotation

 

4.提取Annotation信息:

a) java5之后新增了AnnotatedElement接口,该接口可以接受注释的程序元素。

i. 几个实现类:

1. Class:类定义

2. Constructor:构造器定义

3. Field:类的成员变量定义

4. Method:类的方法定义

5. Package:类的包定义

当一个Annotation类型被定义为运行时Annotation之后,该Annotation才会在运行时可见,JVM才会在转载*.class文件的时候读取保存在class中的Annotation;

b) 程序通过反射获取到某个类的AnnotatedElement对象之后,程序就可以调用下面方法获取到想要的信息:

i. getAnnotation(Class<T> annotationClass):返回该程序元素上存在的指定类型的注释,如果该类型的注释不存在,则返回null

ii. Annotation[] getAnnotations():返回该程序元素上存在的所有注释;

Annotation[] annotations = Class.forName("com.gu.test.ch14.MytagTest").getMethod("info").getAnnotations();

for(Annotation annotation : annotations){

   System.out.println(annotation)}

iii. boolean isAnnotationPresent(Class <? extends Annotation > annotationClass):判断程序上是否存在指定的注释。

c) 获取某个Annotation里面的元数据:

  MytagTest mytagTest=new MytagTest();

  Annotation[] annotations=mytagTest.getClass().getMethod("info").getAnnotations();

  for(Annotation annotation : annotations){

    if(annotation instanceof Mytag){

      System.out.println("Tag is:"+annotation);

      System.out.println("tag name():"+((Mytag) annotation).name());

      System.out.println("tag age():"+((Mytag) annotation).age());

 }

  }

 

5.使用Annotation的示例:

java注释的一条原则:不会对程序构成任何影响;

其实Annotation十分简单,它是对源码增加的一些特殊标记,这些标记可以通过反射获取,当程序获取到这些特殊的标记之后,程序可以做出相应的处理(同时也可以忽略这些标记)

1)  可以通过Annotation为事件源绑定事件监听器

 

6.编译时处理AnnotationAPT(Annotation processing tool)是一种处理注释的工具,它对源代码文件进行检测出其中的Annotation后,对Annotation进行额外的处理。

每个Annotation处理器都需要实现javax.annotation.processing包下的Processor接口。一个Annotation处理器可以处理一个或者多种Annotation.

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值