自定义注解
第一步:
定义一个Person注解类:
/**
* 注解类
*/
@Retention(RetentionPolicy.RUNTIME)//注解可以保留在运行时期
@Target({ElementType.TYPE,ElementType.METHOD})//注解可以贴在类和方法上
public @interface Person {
//引用类型
String name() default "liujun";
//基本数据类型
int age () default 23;
//数组
String [] loves ();
//枚举
Level level();
}
解说:
@Retention :表示注解可以保存在哪一个时期。@Retention(RetentionPolicy.RUNTIME)//注解可以保留在运行时期
自定注解一般都保留在 RUNTIME (运行时期)
@Target:表示注解可以贴在类,方法上,构造器上等等)位置(
ElementType.ANNOTATION_TYPE只能修饰Annotation ElementType.CONSTRUCTOR只能修饰构造方法 ElementType.FIELD只能修饰字段(属性),包括枚举常量 ElementType.LOCAL_VARIABLE只能修饰局部变量 ElementType.METHOD只能修饰方法 ElementType.PACKAGE只能修饰包(少使用) ElementType.PARAMETER只能修饰参数 ElementType.TYPE只能修饰类,接口,枚举
@interface : 定义注解类的表示
定义注解里面的属性:
注解里面的属性支持(基本数据类型,字符,Class,注解,枚举,数组)
//定义一个String 类型的name属性,默认值为 "liujun"
String name() default "liujun";
//定义一个枚举类型的属性
Level level();
附加:
@Documented: 使用@Documented标注的标签会保存到API文档中.
@Inherited: @Inherited标注的标签可以被子类继承到.
第二步:
定义一个枚举类:
public enum Level {
CEO,PM;
}
第三步:
定义一个测试类:
//通过注解注入Person类
@Person(name="xiaomage",age=1,level=Level.CEO, loves = {"足球","桌球"})
public class TestAnnotation {
public static void main(String[] args) {
Class cls=TestAnnotation.class;
//这个TestAnnotation类是否存在Person注解
boolean person=cls.isAnnotationPresent(Person.class);
if(person){
//通过反射获取注解类对象
Person per=(Person) cls.getAnnotation(Person.class);
//获取注解类中的信息
System.out.println(per);
System.out.println(per.name());
System.out.println(per.age());
System.out.println(per.level());
System.out.println(Arrays.toString(per.loves()));
}
}
}
--------------------------------------------------
输出的结果:
@xmg.day24.Person(name=xiaomage, age=1, level=CEO, loves=[足球, 桌球])
xiaomage
1
CEO
[足球, 桌球]
解说:
@Person : 注入Person注解类,并初始化数据
//如果注解类的属性有默认值的可以省略不写,下面给所有的属性赋值初始化 @Person(name="xiaomage",age=1,level=Level.CEO, loves = {"足球","桌球"})
获取Person注解类的对象
Person per=(Person) cls.getAnnotation(Person.class);
获取Person注解类的信息
System.out.println(per.name()); System.out.println(per.age());
第四步:
综合测试(注解写在类上,方法上,参数上,字段上的获取):
1.修改注解类,扩展可注解的范围和所有的字段都添加了默认值
@Retention(RetentionPolicy.RUNTIME)//注解可以保留在运行时期
@Target({ElementType.TYPE,ElementType.METHOD,ElementType.PARAMETER,ElementType.FIELD})//注解可以贴在类,方法,参数,字段上
public @interface Person {
//引用类型
String name() default "liujun";
//基本数据类型
int age () default 23;
//数组
String [] loves () default {"1","2"};
//枚举
Level level() default Level.CEO;
}
2.修改测试类:
//通过注解注入Person类
@Person(level=Level.CEO, loves = {"足球","桌球"})
public class TestAnnotation {
@Person(name="FieldName")
String name;
@Person(name="MethodName")
public static void main(@Person(loves = {"足球2","桌球1"}) String[] args) throws Exception {
//1.获取类上的注解
Class cls=TestAnnotation.class;
//这个类是否存在Person注解
boolean person=cls.isAnnotationPresent(Person.class);
if(person){
System.out.println("--------------------Class-----------------------------");
//通过反射获取注解类
Person per=(Person) cls.getAnnotation(Person.class);
//获取注解类的元素
System.out.println(per);
System.out.println(per.name());
System.out.println(per.age());
System.out.println(per.level());
System.out.println(Arrays.toString(per.loves()));
}
System.out.println("--------------------Method-----------------------------");
//2.获取方法上的注解
Method m=cls.getDeclaredMethod("main", String [].class);
//通过反射获取注解类
Person per=m.getAnnotation(Person.class);
//获取注解类的元素
System.out.println(per.name());
System.out.println("----------------------Parameter---------------------------");
//3.获取参数上的注解
Parameter[] parameters = m.getParameters();
for (Parameter parameter : parameters) {
Person pers=parameter.getAnnotation(Person.class);
System.out.println(Arrays.toString(pers.loves()));
}
System.out.println("----------------------Field---------------------------");
//4.获取字段上的注解:
Field declaredField = cls.getDeclaredField("name");
Person p=declaredField.getAnnotation(Person.class);
System.out.println(p.name());
}
}
解说:
注解信息的获取都是通过反射来获取java中反射的使用