一、什么是注解?
Java 注解用于为 Java 代码提供元数据。作为元数据,注解不直接影响你的代码执行,但也有一些类型的注解实际上可以用于这一目的。Java 注解是从 Java5 开始添加到 Java 的。
我理解的注解就是给类或方法加一个标识,标识也有一些属性,然后我们可以通过判断这些标识以及标识中的属性来做一些特殊处理
注解是通过Java的反射实现的
二、自定义注解
注解通过@interface定义一个注解,使用时使用@注解名来调用
1、定义注解
通过关键字@interface定义注解,且通过元注解标识一些规则
public @interface testAnnotations {}
2、元注解
元注解:用来注解注解的注解,用来定义自定义注解的使用范围等。下面列出几个重要的元注解
Retention:注解的存活时间@Retention(RetentionPolicy.RUNTIME)
- RetentionPolicy.SOURCE 注解只在源码阶段保留,在编译器进行编译时它将被丢弃忽视。
- RetentionPolicy.CLASS 注解只被保留到编译进行的时候,它并不会被加载到 JVM 中。
- RetentionPolicy.RUNTIME 注解可以保留到程序运行的时候,它会被加载进入到 JVM 中,所以在程序运行时可以获取到它们。
注意:一定要加Retention,否则你是解析不到这个类的注解内容的
Target:注解运用到的地方(可以在类前还是方法前使用注解)@Target({ElementType.METHOD, ElementType.TYPE})
ElementType.ANNOTATION_TYPE 可以给一个注解进行注解
ElementType.CONSTRUCTOR 可以给构造方法进行注解
ElementType.FIELD 可以给属性进行注解
ElementType.LOCAL_VARIABLE 可以给局部变量进行注解
ElementType.METHOD 可以给方法进行注解
ElementType.PACKAGE 可以给一个包进行注解
ElementType.PARAMETER 可以给一个方法内的参数进行注解
ElementType.TYPE 可以给一个类型进行注解,比如类、接口、枚举
还有很多其他的元注解Inherited(注解能否被继承)、Repeatable(同一个类或方法是否可以重复使用注解)等
3、注解的属性
注解里可以直接定义String等类型的变量,然后再使用注解时传入变量值
这样可以在获得注解时可以拿到它的属性
比如某个类必须admin权限,这个admin就可以作为一个属性值,然后进一步判断当前登录用户是否有admin权限
自定义注解的一个例子:
package com.xxx.annotations; mport java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME)//元注解-注解存活的时间 @Target({ElementType.METHOD, ElementType.TYPE})//注解可以使用的范围,这里是方法和类上 public @interface testAnnotations { String name();//String类型的注解变量 int age();//int类型的注解变量 }
三、注解的使用
1、注解使用
在类或方法之前,通过【@注解名】的方式使用
a、具体能使用在什么地方,通过注解的元注解Target来决定(如果没使用该元注解,则都可以用)
b、如果注解只有一个属性,则()内不需要写变量名;多个变量的情况需要些【变量名=变量值】
@testAnnotations(name="每天",age=18)//注解的使用,()内为注解的变量值 public class testRun { public static void main(String args[]){ } }
2、解析是否有注解
根据需要的,获取类、方法、成员变量上的注解信息
以下用xx通用表示调用注解方法之前的对象
类:xx=类.class
方法:xx=类.class.getMethod("方法名")
成员变量:xx=类.class.getField("成员变量名")
a、判断是否有注解
xx.getAnnotation(注解类.class)
b、获得所有注解
xx.getAnnotations()
返回的是Annotation[],可以遍历该数组来获取所有的注解
c、获得单个注解
xx.getAnnotation(testAnnotations.class)
d、获得类上注解的变量值
直接通过定义的注解对象然后点出来值就行
例如:
testAnnotations testclass=testRun.class.getAnnotation(testAnnotations.class); testclass.name();
获取注解的一个完整例子如下:
package com.zhuanzhuan.zzappqa.annotations; @testAnnotations(name="每天",age=18)//注解的使用,()内为注解的变量值 public class testRun { @testAnnotations(name="每天3号",age=12) public String hi="hello"; @testAnnotations(name="每天2号",age=16) public void testMethod(){ } public static void main(String args[]) throws NoSuchMethodException, NoSuchFieldException { if(testRun.class.isAnnotationPresent(testAnnotations.class)){//判断类上是否存在该注解 testAnnotations testclass=testRun.class.getAnnotation(testAnnotations.class);//获得类上的注解 System.out.println("类注解的信息:name="+testclass.name()+";age="+testclass.age());//获得注解值并打印 testAnnotations testmethod=testRun.class.getMethod("testMethod").getAnnotation(testAnnotations.class);//获得方法上的注解 System.out.println("方法注解的信息:name="+testmethod.name()+";age="+testmethod.age()); testAnnotations testfield=testRun.class.getField("hi").getAnnotation(testAnnotations.class);//获得成员变量上的注解 System.out.println("成员变量注解的信息:name="+testmethod.name()+";age="+testmethod.age()); }else{ System.out.println("没找到注解"); } } }
执行结果如下:
类注解的信息:name=每天;age=18 方法注解的信息:name=每天2号;age=16
成员变量注解的信息:name=每天2号;age=16