zhouzhaoxin
zhouzhaoxin 主攻python,喜欢读书,喜欢摄影,芒格的忠实追随者。关注各个领域发展,取长补短,擅长结合多学科技术解决问题

Java注解

Java注解

学习注解最重要的就是弄清楚,为什么学习注解?学习注解的好处?学完能做什么? 1、能够读懂别人写的代码,特别是框架相关的代码; 2、能让编程更加简洁,代码更加清晰;

基本概念

注解是Java提供的一种 源程序中的元素关联任何信息和任何元数据的途径和方法。

按来源分类注解

  • java自带注解—— @Override 覆盖了父类的方法、@Deprecation 表示方法已经过时、@Suppvisewarnings 用于通知java编译器忽略特定的编译警告
  • 第三方注解—— 种类很多,Spring的@Resource Hibernate 的@Entity等等
  • 自定义注解—— 自定义注解的结构:元注解(用来注解注解的)、@接口定义、无参无异常的成员方法的定义(成员类型受限:基本数据类型、String、枚举)

按照运行机制分类注解

  • 源码注解——注解只在源码中存在,编译程.class文件时就不存在了
  • 编译时注解——注解在源码和.class文件都会存在的,JDK自带的注解都是编译时注解
  • 运行时注解——在运行阶段还起作用,甚至会影响运行逻辑的注解,比如:@Autowired。

学会自定义注解

学习注解最终就是要把他应用的实际中,其中看懂注解固然重要,会自定义注解并在实际项目中解决问题也不可忽视

要自定义注解就要先了解下面的的元注解:

  • @Target—作用域(constructor(构造方法声明),field(字段声明),local_variable(局部变量声明),method(方法声明),package(包声明),parameter(参数声明),type(类,接口声明))
  • @Retention—生命周期(source:只在源码显示,编译时会丢弃。class:编译时会记录到class中,运行时忽略。runtime:运行时存在,可以通过反射读取)
  • Inherited—标识注解(允许子类继承)
  • Documented—生成Javadoc

下面看一个自定义注解的实例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@Target({ElementType.METHOD,}) //作用域(控制注解能被用在什么地方)
@Retention(RetentionPolicy.RUNTIME) //生命周期
@Inherited //标识注解(允许子类继承)
@Documented //生成javadoc会生成注解信息
public @interface Description {
    //1.类型受限制,包括基本类型及String、Class、Annotation、Enumeration
    //2.若只有一个成员,则名称必须为value(),使用时可以忽略成员名和赋值号(=)
    //3.注解类可以没有成员,称为标识注解
    //4成员无参且无异常声明
    String desc();
    String author();
    //5可指定默认值
    int age() default 18;
}
public @interface Description{
    String desc;
    String author;
    int age default 18;
}

解析注解

概念:通过反射获取类、函数或成员上的运行时注解信息,从而实现动态控制程序运行的逻辑。

只是定义注解而不解析是没有任何用处的,解析注解为注解学习的核心,最主要的是了解两个方法isAnnotationPresent和getAnnotation

@Inherited(子类是否可继承) 对接口interface、方法继承没有作用,对类才有效。 通过反射回去类,函数或成员以上的运行时的注解信息从而实现动态控制程序运行的逻辑

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
//1.使用类加载器加载类
try {
    Class c = Class.forName("com.ann.test.Child");
    //2.找到类上的注解
    boolean isExist = c.isAnnotationPresent(Description.class);
    if(isExist){
        //3.拿到注解实例
        Description d = (Description)c.getAnnotation(Description.class);
        System.out.println(d.value());
    }
    //4.找到方法上的注解
    Method[] ms = c.getMethods();
    for(Method m:ms){
        boolean isMExist = m.isAnnotationPresent(Description.class);
        if(isMExist){
            Description d = m.getAnnotation(Description.class);
            System.out.println(d.value());
        }
    }
    //另外一种解析方法
    for(Method m:ms){
        Annotation[] as = m.getAnnotations();
        for(Annotation a:as){
        if(a instanceof Description){
            Description d = (Description)a;
            System.out.println(d.value());
        }
        }
    }
} catch (ClassNotFoundException e) {
    e.printStackTrace();
}