关于注解

从jdk5开始,java增加了对元数据的支持。也就是Annotation,注解。其实是代码里的特殊标记,这些标记在编译,类加载,运行时被读取,并执行相应的处理。

注解是一个接口,程序可以通过反射来获取指定程序元素dejava.lang.annotation.Annotation对象,通过对象来取得注解里的元数据。

注解能被用啦为程序元素(类,方法,成员变量等)设置元数据。

基本注解

@Override

@Deprecated:Java 9改进了该注解,该注解支持since、forRemoval两个属性。

@SuppressWarnings

@SafeVarargs:Java 9增强了该注解,允许该注解修饰私有实例方法

@FunctionalInterface

这5个第四个是java7新增,最后一个是java8新增。都在java.lang包下。

@Override用来指定方法覆盖。

@Deprecated用于表示某个程序元素已过时。当其他程序使用已过时的类,方法时,编译器会给出警告。java9增加了since表示从那个版本指定为过时,forRemoveal是boolean类型,true代表未来会删除。

@SuppressWarnings 指示该注解修饰的程序元素及该元素的所有子元素,取消显示指定的编译器警告。

@SafeVarargs用于抑制“堆污染”警告。

@Functionallnterface用来指定某个接口必须是函数式接口。

JDK的元注解

@Retention用于指定被修饰的注解可以保留多长时间。,包含一个类型为value的成员变量。只有value为RetentionPolicy.RUNTIME时,JVm可以获取注解信息,程序可以通过反射获取注解信息

使用@Target修饰注解定义,用于指定被修饰的注解能用于修饰哪些线程单元。

使用@Documented用于指定被该元注解修饰的注解类将被javadoc工具提取成文档。

使用@Inherited指定它修饰的注解将具有继承性。

自定义注解

定义新的注解类型使用@interface关键字

 public @interface Test{//定义注解采用@interface来定义,这个注解接口继承了java.annotation.Annotation接口
        String name();//采用没有形参的方法来定义注解的成员变量,返回值表示注解的类型
        int age() default 34;//可以为成员变量指定默认值。
    }
    @Test(name="stu",age=12)//注解可以修饰类,接口,方法等任何元素。一旦定注解定义了成员变量,那么就一定要为他赋值。
    public  class MyClass{
        @Test(name="stu")//使用了默认值的成员变量可以不为之指定值
        public void info(){
            //标记注解:没有定义成员变量的注解,仅利用自身的存在与否来提供信息
            //元数据注解:包含成员变量的注解。可以接受更多的元数据。
        }
    }

注解需要由开发者提供相应的工具来提取处理注解信息

java使用java.lang.annotation.Annotation接口来代表程序元素签名的注解。java5在java.lang.reflect包下新增了AnnotatedElement接口,代表程序中可以接受注解的程序元素。

该包下包含一些实现反射功能的工具类。只有当定义注解时,是用了@Retention的Runtime模式,该注解才能在运行时可见,JVM才会在装在class文件时读取保存在class文件中的注解信息。

AnnotatedElement接口是所有程序元素如class,MEthod等的父接口。所以程序通过反射获取了某个类的该接口对象。之后,程序就可以调用该对象的如下几个方法来访问注解信息。

getAnnotation。。。等等。

仅仅使用注解标记程序元素,对程序不会有任何影响,为了让注解起作用,必须为这些注解提供一个注解处理工具。

工具通过反射来获取标记,获取这些标记后,程序可以做出相应的处理。对于标记注解,程序通过判断该注解存在与否,决定是否允许指定方法。

重复注解,java8以前,同一个元素前面最多只能使用一个相同类型的注解,如果使用多个,必须使用注解容器。

从java8开始,允许使用多个相同的类型的注解来修饰同一个类。但是需要开发。

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Repeatable(FkTags.class)
public @interface FkTag
{
	// 为该注解定义2个成员变量
	String name() default "疯狂软件";
	int age();
}


// 指定该注解信息会保留到运行时
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface FkTags
{
	// 定义value成员变量,该成员变量可接受多个@FkTag注解
	FkTag[] value();
}

  使用@Repeatable是注解可以重复。

然后定义该注解的容器。

注解容器的的保留期必须比它所包含的注解保留期更长。

重复注解只是一种简化写法,其实多个重复注解会被作为容器注解的value成员变量的数组元素。

类型注解

java8位ElementType增加了两个枚举值。这样允许定义枚举是使用@target(TYPE_USE)修饰符。可以在任何地方出现类型注解。使得程序执行更严格的类型检查。但是只写注解没有作用,需要使用注解处理工具。第三方框架一般会提供类型注解检查工具。

APT,是一种注解处理工具,他对源代码文件进行检测,找出源文件所包含的注解信息,然后针对注解信息进行额外处理。

处理注解时,可以根据源文件中的注解生成额外的源文件和其他的文件,还会编译生成的源代码文件和原来的源文件,将他们一起生成class文件。

简化开发者工作量,APT可以在编译程序源代码同时生成一些附属文件。

java提供的javac.exe工具有一个-processor选项,可以指定一个注解处理器,会在编译时提取并处理java源文件中的注解。

原文地址:https://www.cnblogs.com/tomato190/p/12441893.html