Annotation笔记

文章目录

  • Annotation
    • 参考
    • metadata
      • metadata的作用
    • annotation的分类
    • 自定义annotation
      • 使用
      • 元注解
        • @Retention
          • 实例
        • @Documented
        • @Target
        • @Inherited
        • @Repeatable
          • 实例
      • 注解的属性
    • 例子
      • java自带的注解
      • 注解的基本信息
      • 带属性的注解
      • 注解的数组类型的属性
      • 注解的枚举类型的属性

@Date: 2018-11-05

Annotation

  • Annotation就是java提供了一种元程序中元素关联任何信息和任何元数据(metadata)的途径和方法。
  • Annotation本质上是一个特殊的java接口,主要定义了名字,类型,成员默认值,成员变量是受限制的。
  • 行为类似public, final等修饰符号,可以当做修饰一样被使用。

参考

java 元数据metadata
元数据(MetaData)的简单理解
JAVA-元数据
java注解的基本含义
秒懂java注解
Java基础加强总结(一)——注解(Annotation)

metadata

  • 元数据是关于数据的数据。
  • 在编程语言中是添加到程序元素(如类、方法、字段等)上的额外的信息
  • 对数据进行描述性说明的数据。

metadata的作用

  1. 编写文档:通过代码里标识的元数据生成文档
  2. 代码分析:通过代码里标识的元数据对代码进行分析
  3. 编译检查:通过代码里标识的元数据让编译器能实现基本的编译检查

JDK5.0前程序的元数据存在的形式仅限于xml 部署描述文件、java注释或javadocxml 部署描述文件、java注释或javadoc。
对Struts来说就是struts-config.xml,对ejb来说就是ejb-jar.xml和厂商自定义的xml文件,对hibernate来说就是hbm文件。元数据的概念在.net中成为Attribute。
在Java中元数据以标签的形式存在于Java代码中(主要为Annotation),元数据标签的存在并不影响程序代码的编译和执行,它只是被用来生成其它的文件或针在运行时知道被运行代码的描述信息。

annotation的分类

分为:

  • java自带注解@SuppressWarnings, @Deprecated, @Override, @SafeVarargs, @FunctionalInterface
  • 自动注解
名称 作用
@SuppressWarnings 关闭编译器的某些警告
@Deprecated 不赞成使用的代码或废弃的代码
@Override 当前方法定义覆盖超类的方法

自定义annotation

public @interface MyAnnotation{}

使用

@MyAnnotation
public class MyTest {
}

元注解

定义:注解的注解,也可以称为元标签。分为: @Retention、@Documented、@Target、@Inherited、@Repeatable 5 种。

@Retention

定义注解的生命周期。

名称 生命周期
RetentionPolicy.SOURCE 只在源码阶段保留,编译器编译时,它将被忽略
RetentionPolicy.CLASS 只保留编译进行的时候,不会加载到JVM
RetentionPolicy.RUNTIME 保留到程序运行的时候,会被加载的JVM,程序运行的时候可以用他们
实例
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
}

@Documented

将注解中的元素包含到javadoc中。

@Target

指明注解使用的地方。

说明
ElementType.ANNOTATION_TYPE 给一个注解进行注解
ElementType.CONSTRUCTOR 给一个构造函数进行注解
ElementType.FIELD 属性
ElementType.LOCAL_VARIABLE 局部变量
ElementType.METHOD 方法
ElementType.PACKAGE
ElementType.PARAMETER 参数
ElementType.TYPE 类型,包含类、数组、枚举

@Inherited

并不是指注解本身可以继承,如果一个超类@Inherited注解过,那么它的子类没有被任何类注解应用的话,那么子类就继承了这个超类的注解。

@Repeatable

可重复的注解。

实例
@interface Persons {
    Person[] persons;
}

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

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

}

注解的属性

也叫成员变量。

  • 注解只有成员变量,没有方法。
  • 成员变量以无形参的方式申明。
  • 用default来给定默认值。
  • 返回值定义了成员变量的类型。
  • 赋值方式value=""。
  • 8中基本数据类型,加类,接口,注解和他的数组。
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface TestAnnotation {

    public int id() default -1;

    public String msg() default "Hi";

}

@TestAnnotation(id=90, msg="abc")
public class Test{
}

例子

java自带的注解

public class AnnotationTest {
   /**
     * SuppressWarnings抑制警告 但是Deprecated由于IDE的原因依旧存在
     * @param args
     */
    @SuppressWarnings("all")
    public static void main(String[] args) {
        //i应该有unused的警告,注解会关掉改警告
        int i = 0;
        AnnotationTest.SayHello();
    }

    /**
     * Annotation表明这是一个过时的方法
     */
    @Deprecated
    public static void SayHello() {
        System.out.println("Hello World!");
    }

    /**
     * 表明这是重写父类的方法
     * @return
     */
    @Override
    public  String toString() {
        return super.toString();
    }
}

注解的基本信息

/**
 * @Retention: 定义了注解的生命周期
 * @Target: 定义了注解的作用对象
 */
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD})
public @interface MyAnnotation {
}

@MyAnnotation
public class MyAnnotationUse {
    public static void main(String[] args) {
        //通过反射检查类是否有注解
        if(MyAnnotationUse.class.isAnnotationPresent(MyAnnotation.class)) {
            MyAnnotation myAnnotation = (MyAnnotation)MyAnnotationUse.class.getAnnotation(MyAnnotation.class);
            System.out.println(myAnnotation);
            //Result: @annotationtest.MyAnnotation()
        }
    }
}

带属性的注解

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface MyAnnotationWithAttribute {
    //默认注解属性是public 不可以是基础类型的封装类型
    //并且都带有括号()
    long id() default 1000;
    String color();
}

@MyAnnotationWithAttribute(color = "Red")
public class MyAnnotationWithAttributeTest {
    public static void main(String[] args) {
        //通过反射获得Annotation的propety并打印
        MyAnnotationWithAttribute myAnnotationWithAttribute = (MyAnnotationWithAttribute)
                MyAnnotationWithAttributeTest.class.getAnnotation(MyAnnotationWithAttribute.class);
        System.out.println(myAnnotationWithAttribute.id() + " " + myAnnotationWithAttribute.color());
        //Result: 1000  Red
    }
}

注解的数组类型的属性

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD})
public @interface ArrayAnnotation {
    int[] value() default {4, 3, 5};
}

@ArrayAnnotation
public class ArrayAnnotationTest {
    public static void main(String[] args) {
        //如果ArrayAnnotation没有定义@Retention(RetentionPolicy.RUNTIME)这里会出现NPE
        ArrayAnnotation arrayAnnotation = (ArrayAnnotation)
                ArrayAnnotationTest.class.getAnnotation(ArrayAnnotation.class);
        System.out.println(arrayAnnotation.value()[0]);
        //4
    }
}

注解的枚举类型的属性

public enum Color {
    White,
    Black,
    Red
}

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD})
public @interface EnumAnnotation {
    Color value() default Color.Black;
}

@EnumAnnotation(Color.Red)
public class EnumAnnotationTest {
    public static void main(String[] args) {
        //注解默认值为Black 类又赋值为Red
        EnumAnnotation enumAnnotation = (EnumAnnotation)
                EnumAnnotationTest.class.getAnnotation(EnumAnnotation.class);
        System.out.println(enumAnnotation.value());
        //Result: Red
    }
}

你可能感兴趣的:(java)