以下为本人的学习笔记

1.认识Annotation

  JDK1.5开始,java增加了对元数据(即类的组成单元数据)的支持,也就是(Annotation)注解,它是代码里做的特殊标记,这些标记可以在编译,类加载,运行时在不改变原有逻辑的情况下,被读取(通过反射来读取),并执行相应 的处理,通过使用Annotation,程序员可以在源文件中嵌入一些补充从信息。代码分析工具,开发工具和部署工具可以通过这些补充信息进行验证或者进行部署。Annotation类似于修饰符一样被使用,可以用于包,类,构造方法,方法,成员变量,局部变量的声明。

  元数据可以说是一个属性,解释数据的数据。如一个属性age的值为18,那么这个解释18的字段age就是元数据。

  注解也可以说是一个描述信息,把信息再解析。

  注解的本质是标记,他所有的功能都依赖于对于这个注解解释性的代码,通常需要结合反射来编写解释下代码。

注意:

Annotation是一个接口

java.lang.Annotation接口

2.系统定义的Annotation

在JDK1.5之后,在系统中提供了三个Annotation,分别是:@Override(译:覆盖)、@Deprecated(译:已弃用)、@SupperssWarings。

@Override

表示验证当前的方法是否覆盖超类中的方法(即重写父类方法)。如果你一不小心拼写错误,或者方法签名对不上被覆盖的方法,编译器就会发出错误提示

@Deprecated

表示的是一个类或方法已经不再建议继续使用了,标记为已过时

@SupperssWarings

表示关闭不当的编译器警告信息

Annotation 说明
@SupperssWarings("unchecked") 未检查的转化,如集合没有指定类型
@SupperssWarings("unused") 未使用的变量
@SupperssWarings("resource") 有泛型未指定类型
@SupperssWarings("path") 在类路径,原文件路径中有不存在的路径
@SupperssWarings("deprecation") 使用了某些不赞成使用的类和方法
@SupperssWarings("fallthrough") switch语句执行到底没有break关键字
@SupperssWarings("serial") 某类实现Serializable但是没有定义serialVersionUID这个需要但是不必须的字段
@SupperssWarings("rawtypes") 没有传递带有泛型的参数
@SupperssWarings("all") 全部类型的警告(用这一条就够了)

3.自定义Annotation

注解应用三个步骤:

1)编写注解

2)在类上应用注解

3)对应用了注解的类进行反射操作的类

自定义Annotation的语法如下:

访问控制权限@interface Annotation 名称{}

@interface : 定义一个注解的关键字

例如:

public @interface MyAnnotation{}

//1.自定义注解
//表示该注解的作用范围在运行时存在
@Retention(RetentionPolicy.RUNTIME)
//用于生成文档
@Documented
//用于表示注解的应用范围(类型,方法,属性,构造器,参数,局部变量,包,Annotation)
@Target(ElementType.TYPE)
@Inherited//子类可继承
public @interface MyAnnotation{
//定义变量,注意:变量后要加括号(),且调用此注解时必须设置变量名
 public String name();
 
 public int age() default 2;//给变量设置默认值
 
 public String[] like();//定义一个数组,调用此注解时变量名要含大括号{}
 
 public COlor color();//定义一个枚举类型的变量
 
}
​
public enum Color{
 RED,GREEN,BLUE;
}
//2.使用注解
@MyAnnotation(name="wan",like = {"金鱼","草鱼"},color = Color.RED)
public class Cat{
 private String name;
 private int age;
 public String[] like;
 private Color color;
  ...(构造方法,getter(),setter())
}
public class AnnotationDemo{
/**
反射来处理注解
*/
@Test
 public void test2(){
   Class<Cat> catClass = Cat.class;
   //获取类上应用的指定注解
   MyAnnotation annotation = CatClass.getAnnotation(MyAnnotation.class);
   //获取注解上变量值
   String name = annotation.name();
   int age = annotation.age();
   Color color = annotation.color();
   String[] like = annotation.like();
   try{
     //通过反射实例化对象,调用对象的方法存储注解上的值
        Cat cat =catClass.newInstance();
     cat.setName(name);
     cat.setAge(age);
     cat.setLike(like);
     cat.setColor(color);
     System.out.println(cat);
    }catch(InstantiationException e){
     e.printStackTrace();
    }catch(IllegalAccessException e){
     e.printStackTrace();
    }
​
  }
 
 
 
}  

4.Retention和RetentionPolicy

Annotation要想决定其作用的范围,通过@Retention(译:保持)指定,而Retention指定的范围由RetentionPolicy(policy,译:方针,政策,原则)决定,RetentionPolicy指定了三种范围:

范围 说明
public static final RetentionPolicy SOURCE 在java源程序中存在(提供给编译器使用)
public static final RetentionPolicy CLASS 在java生成的class存在
public static final RetentionPolicy RUNTIEM 在java运行的时候存在(我们通常使用这个范围)

示例:

@Retention(value = RetentionPolicy.RUNTIME)

public @interface MyAnnotation{

public String name();

}

5.反射与Annotation

一个Annotation真正起作用,必须结合反射机制,在反射中提供了以下的操作方法:

java.lang.reflect.AccessibleObject(供虚拟机使用)

Method 说明
public boolean isAnnotationPresent(Class<? extends Annotation> annotationClass) (present,译:目前,出现) 判断是否是指定的Annotation
public Annotation[] getAnnotations() 得到全部的Annotation

注解在目前而言最主流的应用就是代替配置文件,例如Spring、SpringBoot等,注解具有开发效率高,成本低的特点,缺点是耦合性高,不利于维护

6.@Documented注解

此注解表示的是文档化,可以在生成doc文档的时候添加注解,即生成文档时,注释一起生成

7.@Target注解

@Target注解(用来注释注解)表示的是一个Annotation的使用范围,例如:之前定义的MyAnnotation可以在任意的位置上使用(没有写这个注解,就所有地方可以使用)

范围 说明
public static final ElementType TYPE 只能在类或接口或枚举上使用
public static final ElementType FIELD 在成员变量中使用
public static final ElementType METHOD 在方法中使用
public static final ElementType PARAMETER 在参数上使用
public static final ElementType CONSTRUCTOR 在构造中使用
public static final ElementType LOCAL_VARIABLE 局部变量上使用
public static final ElementType ANNOTATION_TYPE 只能在Annotation中使用
public static final ElementType PACKAGE 只能在包中使用

8.@Inherited注解

@Inherited表示一个Annotation是否允许被其子类继承下来(使用时表示允许)

■免责申明
⒈ 本站是纯粹个人学习网站,与朋友交流共赏,不存在任何商业目的。
⒉ 本站利用了部分网络资源,版权归原作者及网站所有,如果您对本站所载文章及作品版权的归属存有异议,请立即通知我们,我们将在第一时间予以删除,同时向你表示歉意!

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。