全面解析Java注解
概念
- Java提供了一种源程序中的元素关联任何信息和任何元数据的途径和方法
注解的分类
- 源码注解:注解只在源码中存在,编译成.class文件后就不存在了
- 编译时注解:注解在源码和
.class
文件中都存在 - 运行时注解:在运行阶段还起作用,甚至会影响运行逻辑
自定义注解
@Target({ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Description {
String desc();
String author();
int age() default 18;
}
- 上面的自定义注解使用
@interafce
关键字定义注解 - 成员函数没有参数,没有异常声明
- 可以用
default
为成员指定一个默认值 - 成员的类型是受限的,合法的类型包括原始类型以及String,Class,Annotation,Enumeration
- 如果注解直邮一个成员,则该成员必须取名为
vlaue()
,在使用的时候可以忽略成员名和赋值号(=) 注解类可以没有成员,没有成员的注解称为标识注解
- 上面自定义注解的前四行就是元注解
@Target({ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
- 第一行表示注解的作用域
- 第二行表示声明周期
- 第三行表示是否子类继承,如果添加这句话说明子类的注解中将包含且只包含该类的类注解
- 第四行表示生成javadoc的时候会产生该注解
使用自定义注解
- 使用自定义注解的语法:
@<注解名>(<成员名1>=<成员值1>,<成员名2>=<成员值2>,...)
@Description(desc="I am SuperMan",author="Jacob",age=18)
public String eyeColor(){
return "red";
}
解析注解
- 概念:通过反射来获取类、函数或者成员上的运行时注解信息,从而实现动态控制程序运行的逻辑
package com.coderbean;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
/**
* Created by Chang on 16/1/3.
*/
public class ParseAnn {
public static void main(String[] args) {
//1.使用类加载器加载类
try {
Class c = Class.forName("com.coderbean.Child");
//2.找到类上面的注解
if(c.isAnnotationPresent(Description.class)){
//3.拿到注解治理
Description description = (Description)c.getAnnotation(Description.class);
System.out.println(description.value());
}
//找到方法上的注解
Method[] methods = c.getMethods();
for(Method method:methods){
if(method.isAnnotationPresent(Description.class)){
Description description = (Description)method.getAnnotation(Description.class);
System.out.println(description.value());
}
}
//另外一种解析方法
for(Method method:methods){
Annotation[] annotations = method.getAnnotations();
for(Annotation annotation:annotations){
if(annotation instanceof Description){
Description description = (Description)annotation;
System.out.println(description.value());
}
}
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}