注解

1.概念

Java软件开发过程:

  • 第一个过程:我们所有的代码,配置信息全部写在类中,配置文件越来越多,软件的可维护性差

  • 第二个过程:注解替代配置文件(JDK1.5新内容),仅仅是一个梦

  • 第三个过程:注解+配置文件

2.元注解

即修饰注解的注解

  • @Target 表示注解可以声明的位置,默认不写表示在任何位置都可以使用。TYPE,METHOD,FIELD,CONSTRUCTOR,LOCAL_VARIABLE,PARAMETER

  • @Retention 表示注解的生命周期

    • CLASS表示在二进制文件中生效

    • RUNTIME表示在程序运行时生效

    • SOURCE表示在Java源代码中生效

    • 生命周期长度 SOURCE < CLASS < RUNTIME

  • Documented 被此注解修饰的注解表示在doc文档注释中保留此注释

  • Inherited 表示被此注解修饰的注解可以被子类保留

注解的属性(给注解添上一些属性用于实现一些数值的传递、保留)

  1. 注解中不能写方法,也没有抽象方法 书写格式:Type name();

  2. 注解中的属性支持的数据类型

8中基本类型、String、枚举、Class和其对应的数组 共(8+3)*2 = 22种

  1. 注解中的属性名为value并且只有一个属性的时候可以直接写值。数组的话直接大括号,大括号内写值

  2. 注解中可以写枚举类

注解的获取:

通过反射获取注解的内容

  1. 获取类上声明的注解,先获取到当前类对象,使用类对象调用getAnnotations()方法,得到一个注解数组

  2. 获取方法上声明的注解,先获取到当前类对象,再使用getMethods()方法获取到所有的方法对象,使用方法对象调用getAnnotations()方法,得到一个注解数组

  3. 获取字段上声明的注解,先获取到当前类对象,再使用getFields()方法获取到所有的字段对象,使用字段对象调用getAnnotations()方法,得到一个注解数组

  4. 获取构造方法上声明的注解,先获取到当前类对象,再使用getConstructors()方法获取到所有的构造器对象,使用构造器对象调用getAnnotations()方法,得到一个注解数组

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
​
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface HostName {
    String a();
    String [] values();
}
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
​
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Port {
    String value();
}
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.Arrays;
import javax.jws.HandlerChain;
/**
 *  自定义注解 然后再本类中
 *  通过反射获取到注解的值
 * @author ausu
 */
@HostName(a = "a" , values = {"a"})
 public class ConnectionInfo{
    // 通过注解给属性赋值 但是只是可以通过反射的方式获取到此值
    // 不影响当前属性原来的方式使用
    @HostName(a = "localhost",values = {"a","b"})
    private String hostName;
    @Port("3306")
    private String port;    
    
    @HostName(a = "127.0.0.1",values = {"a","b"})
    @Port("8080")
    private String connInfo;
    public static void main(String[] args) throws Exception {
        
        Class<?> stuClass = Class.forName("com.qfedu.test3.ConnectionInfo");
        Field[] fields = stuClass.getDeclaredFields();
        System.out.println(fields.length);
        for (Field field : fields) {
            if(field.isAnnotationPresent(HostName.class)) {
                HostName annotation = field.getAnnotation(HostName.class);
                System.out.println(annotation.a());
                System.out.println("获取注解数组类型的属性" + Arrays.toString(annotation.values()));
            }
            
            if(field.isAnnotationPresent(Port.class)) {
                Port annotation = field.getAnnotation(Port.class);
                System.out.println(annotation.value());
            }
        }       
        
        Field connInfoField = stuClass.getDeclaredField("connInfo");
        Annotation[] annotations = connInfoField.getAnnotations();
        for (Annotation annotation : annotations) {
            System.out.println(annotation.annotationType());
            // 这里通过获取注解的类型 getName方法 判断是否使用了某个注解  
        }
        
        HostName annotation1 = connInfoField.getAnnotation(HostName.class);
        System.out.println(annotation1.a());
        Port annotation2 = connInfoField.getAnnotation(Port.class);
        System.out.println(annotation2.value());
    }
}

 

posted on 2020-08-31 08:54  zitian246  阅读(62)  评论(0)    收藏  举报