枚举类与注解 之 注解讲解

注解:

在实际的开发过程中我们会经常使用到注解,如果在开发过程中你不懂注解,那么说明你不是一名合格的程序员。所以我们有必要对注解进行深入的了解。

Annotation可以像修饰符一样被使用,可用于修饰包,类,构造器,方法,成员变量,参数,局部变量的声明,这些信息被保存在Annotaion的“name=value”对中。

jdk内置了三个基本的注解:@Override @Deprecated @SuppressWarnings

我们在学习JAVA基础的时候,经常使用到的注解有:

@Override 告诉编译器这个方法是覆盖父类的方法

@WebServlet("/test") 表示某个类是一个Servlet,Web容器就会识别这个注解,在运行的时候调用它。

@Controller("/test") 表示某个类是一个控制器,告诉spring框架该类是一个控制器。

注解和注释是完全不同的两个东西,看起来有点类似,其实完全不同,注解会影响程序的运行。注释是给开发人员看的,不会影响程序的编译和运行。注解并不是给开发人员看的,是用于给程序看的,会影响程序的编译和运行,比如给编译器、tomcat、框架看的。

1.1注解的作用范围

自定义开发一个web容器,基本功能是加载servlet,需要管理它的生命周期,所以必须先识别程序中的哪些类是Servlet。程序启动的时候,扫描所有的类,找出添加了@WebServlet注解的类,进行加载(类似于spring IOC容器的启动过程)。

@WebServlet 是在程序运行的时候起作用的,那么JAVA就把他的作用范围规定为RUNTIME.

@Override 是给编译器看到饿,编译器工作的时候识别出包含了@Override 注解的方法,就去检查他上层父类的相应方法,存在则通过,否则报错。

@Override是编译的时候起作用,JAVA就把他的作用范围规定为SOURCE.

@Test 是生成测试代码,一般在框架中使用的比较多,作用范围是SOURCE.

JDK5.0提供了4个标准的meta-annotaion类型的元注解,分别是:target retention documented inherited

1.2@Target 指定注解针对的地方

ElementType:

ElementType.TYPE : 针对类 、接口

ElementType.FIELD : 针对成员变量

ElementType.METHOD: 针对成员方法

ElementType.PARAMETER : 针对方法参数

ElementType.CONSTRUCTOR: 针对构造器

ElementType.PACKAGE:针对包

ElementType.ANNOTATION: 针对注解

1.3 @Retention 指定注解的保留域

也可以理解为注解的存活时间

RetentionPolicy:

RetentionPolicy.SOURCE 源代码级别,由编译器处理,处理之后就不再保留

RetentionPolicy.CLASS 注解信息保留到类对应的class 文件中,这是一个默认行为,也就是说,如果不进行指定的时候,默认就是他。

RetentionPolicy.RUNTIME 由JVM读取,运行的时候使用,也就是说,只有声明为runtime声明周期的注解,才能通过反射进行获取。

1.4@Documented:(在实际的使用中比较少)

用于指定被该元Annotation修饰的Annotation类将被javadoc工具提取成文档,默认情况下,javadoc是不包括注解的。

定义为Documented的注解必须设置Retention 值为 RUNTIME.

1.5@Inherited:(在实际的使用中比较少)

被他修饰的Annotation将具有继承性。如果某个类使用了被该@Inherited修饰的Annotation,则其子类将自动具有该注解。

比如:如果把标有@Inherited注解的自定义的注解标注在类级别上,子类则可以继承父类级别的注解。

​ 实际应用中,使用较少

1.6自定义注解

package com.annotationpractice;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

//添加源注解,用来指明当前的注解是干什么用的
@Target(ElementType.METHOD)//表示这个注解只能添加到方法上面
@Retention(RetentionPolicy.RUNTIME)//表示该注解只能在运行的时候进行调用
public @interface InitMethod {
}

package com.annotationpractice;

public class InitDemo {
    @InitMethod
    public void init(){
        System.out.println("init......");
    }

    public void test(){

    }
}
package com.annotationpractice;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * 测试注解的使用
 */
public class Test {
    public static void main(String[] args) throws NoSuchMethodException, ClassNotFoundException, IllegalAccessException, InvocationTargetException, InstantiationException {
        Class<?> clazz = Class.forName("com.annotationpractice.InitDemo");
        Method[] methods = clazz.getMethods();
        if(null != methods){
            for (Method method : methods) {
                boolean flagInitMethod = method.isAnnotationPresent(InitMethod.class);//看看该方法中有没有该注解
                if(flagInitMethod){
                    method.invoke(clazz.getConstructor(null).newInstance(null),null);
                }
            }
        }
    }
}
运行结果:init......

注意:自定义注解必须配上信息处理流程才有意义。也就是说必须要使用反射的方式。

1.7 jdk8中注解的新特性 可重复注解 类型注解

可重复注解

①在MyAnnotation上声明@Repetable,成员值为MyAnnotations.class

②MyAnnotation的Target和Retention等元注解与MyAnnotations相同

jdk8之前写该注解:

////这是在jdk8之前的写法
//@MyAnnotations({@MyAnnotation(value = "hi"),@MyAnnotation(value = "abc")})

jdk8写该注解:

@MyAnnotation(value = "abc")
@MyAnnotation(value = "hi")
package com.annotationpractice;

import com.sun.deploy.security.ValidationState;

import java.lang.annotation.*;
import java.lang.reflect.Type;

import static java.lang.annotation.ElementType.*;

/**
 * 自定义注解
 */
@Repeatable(MyAnnotations.class)
@Target({TYPE,FIELD,METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
    String[] value() default "hello";
}

package com.annotationpractice;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import static java.lang.annotation.ElementType.*;

/**
 * 自定义注解
 */
@Target({TYPE,FIELD,METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotations {
    MyAnnotation[] value();
}

package com.annotationpractice;

/**
 * 如何自定义注解 参照@suppresswarning定义
 * 1.注解声明为 @interface
 * 2.内部定义成员,通常使用value表示
 * 3.可以指定成员的默认值,使用default定义
 * 4.如果自定义注解没有成员,表明是一个标识作用
 *
 */
//@MyAnnotation(value = "hi")  //当然这里可以不指定,也是可以的
////这是在jdk8之前的写法
//@MyAnnotations({@MyAnnotation(value = "hi"),@MyAnnotation(value = "abc")})
@MyAnnotation(value = "abc")
@MyAnnotation(value = "hi")
public class Person {
    private String name;
    private int age;

//    @MyAnnotation  //因为在注解内部已经指定了值了,所以,这里如果没有特别的需要,也是可以不写值的。
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public Person() {
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

类型注解

ElementType.TYPE_PARAMETER: 表示该注解能写在类型变量的声明语句中(如:泛型声明)

ElementType.TYPE_USE: 表示该注解能写在使用类型的任何语句中

package com.annotationpractice;

import com.sun.deploy.security.ValidationState;

import java.lang.annotation.*;
import java.lang.reflect.Type;

import static java.lang.annotation.ElementType.*;

/**
 * 自定义注解
 */
@Repeatable(MyAnnotations.class)
@Target({TYPE,FIELD,METHOD,TYPE_PARAMETER,TYPE_USE})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
    String[] value() default "hello";
}

package com.annotationpractice;

import java.lang.reflect.Array;
import java.util.ArrayList;

/**
 * 类型注解
 */
public class Generic<@MyAnnotation T> {
    public void show() throws @MyAnnotation RuntimeException{
        ArrayList<@MyAnnotation String> list = new ArrayList<>();
        int num=(@MyAnnotation int) 10L;
    }
}

案例:简单的测试框架

参考网址:https://blog.csdn.net/zzu_seu/article/details/104673681

原文地址:https://www.cnblogs.com/dongyaotou/p/15732559.html