注解即标记(也可以理解为索引)和反射相辅相成,在写框架需要动态加载的时候需要用到注解,
注解负责给对象(万事万物皆对象,所有类,方法,属性都为对象)标记好名字,有了注解我们就有了所需要的类,方法,属性。动态获取,松耦合。
1.新建一个注解类:
package annoDemo
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
//表示注解的作用域,例如:ElementType.TYPE 类、接口声明 ,ElementType.METHEOD 方法声明,ElementType.FIELD 字段声明
@Target({ElementType.TYPE,ElementType.METHOD,ElementType.FIELD})
@Target({ElementType.TYPE,ElementType.METHOD,ElementType.FIELD})
//表示注解的生命周期
//RetentionPolicy.SOURCE源码注解,表示只在源码中存在,编译成.class文件就不存在了,也就是编译时会丢弃;
//RetentionPolicy.CLASS 编译时注解,在源码和.class文件中都存在,也就是编译时会记录到class中,运行时忽略
//RetentionPolicy.RUNTIME 运行时注解,在运行时存在,可以通过反射读取出来
@Retention(RetentionPolicy.RUNTIME)
//允许子类继承(只能继承类声明的注解)(实现接口是不能继承注解的)
@Inherited
//生成javadoc时会包含注解
@Documented
public @interface Demo2 { //使用@interface关键字 定义注解
String str();//成员以无参,无异常方式声明
double d();
int age() default 18;//可以用default为成员指定默认值
}
2.在类中使用注解
package annoDemo;
@Demo2(str="123",d=1.2)
public class Animal {
@Demo2(str="234",d=2.5)
public String color;
@Demo2(str="345",d=3.7)
public void sing(){}
}
public class Animal {
@Demo2(str="234",d=2.5)
public String color;
@Demo2(str="345",d=3.7)
public void sing(){}
}
3.解析注解
package annoDemo;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class Test {
public static void main(String[] args) {
try {
//1.反射得到class对象
Class c = Class.forName("annoDemo.Animal");
//找到类上面的注解
boolean isexist = c.isAnnotationPresent(Demo2.class);
if(isexist){
//得到注解实例
Demo2 d2 = (Demo2)c.getAnnotation(Demo2.class);
System.out.println("str:"+d2.str()+" d:"+d2.d()+" age:"+d2.age());
}
//拿到方法上的注解
Method[] mArray = c.getMethods();
for(Method m : mArray){
boolean isexist2 = m.isAnnotationPresent(Demo2.class);
if(isexist2){
Demo2 d = (Demo2)m.getAnnotation(Demo2.class);
System.out.println("str:"+d.str()+" d:"+d.d()+" age:"+d.age());
}
}
//拿到成员上的注解
Field[] fArray = c.getFields();
for(Field f : fArray){
boolean isexist3 = f.isAnnotationPresent(Demo2.class);
if(isexist3){
Demo2 d = (Demo2)f.getAnnotation(Demo2.class);
System.out.println("str:"+d.str()+" d:"+d.d()+" age:"+d.age());
}
}
//另一种方式解析注解,如下:
for(Method m:mArray){
Annotation[] an = m.getAnnotations();
for(Annotation a : an){
if(a instanceof Demo2){
Demo2 d = (Demo2)a;
System.out.println("str:"+d.str()+" d:"+d.d()+" age:"+d.age());
}
}
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
控制台打印如下:
str:123 d:1.2 age:18
str:345 d:3.7 age:18
str:234 d:2.5 age:18
str:345 d:3.7 age:18