自定义注解 (只可以解析RUNTIME的才有效果)
- 只有一个成员的注解
public @interface Description{
String desc();
}
@Description(desc="the name method")
不会报错。 但不符合规范,既然只有一个成员,就要使用value作为成员名,改成:
public @interface Description{
String value();
}
然后在使用注解的时候,直接赋值,不写成员名和等号:
@Description("the name method")
以上方式,约定俗成,比较直观。
- 没有成员的注解——标志注解(比如常见的@Override),在使用的时候不加括号。
- 当一个方法被规定为({ElementType.METHOD})就表示只能用于方法的注解,如果用在类上面,就会报错(添加 ElementType.TYPE 则可适用于类)。这里没有包含关系,例如只写ElementType.TYPE 则不能对方法进行注解,只能对类或接口进行注解。
- @Documented(属于标识注解,生成javadoc时会包含注解) 创建一个Javadoc :右击项目--> Export --> Java --> Javadoc --> next -->Browser 选择要存放的文件夹。点击finish就生成成功了。 打开这个文件夹,点击index.html,就能查看该项目的一些摘要。
package com.test;
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;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Boy {
//public String name(String name);//这是错误的
//注解的方法不可带参数
//注解的方法叫做成员
public String name();
//public Object jump();
//注解方法返回值类型限定为:基本类型、String、Enums、Annotation或者是这些类型的数组;
public int jump();
//注解方法可以有默认值;
public int age() default 18;
}
使用自定义注解语法
@<注解名>(<成员名1>=<成员的值1>,<成员名2>=<成员的值2>,)
@Boy(name="king",age=20)
public String User(){
return "user";
}
解析注解
概念:通过反射获取类、函数或成员上的运行时注解信息,从而实现动态控制程序运行的逻辑。
isAnnotationPresent() getAnnotation() getAnnotations() 类上的注解,方法上班的注解
1.定义了一个Boy注解
package com.test;
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;
@Target({ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Boy {
public String name();
public int age() default 18;
}
定义了一个使用Boy注解的Student
package com.test;
@Boy(name="king",age=20)
public class Student {
@Boy(name="kk",age=25)
public String user() {
return "ddd";
}
}
解析Student上的boy注解
package com.test;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class Test {
public static void main(String[] args) throws ClassNotFoundException {
//1.使用类加载器加载类
Class c = Class.forName("com.test.Student");
//2.找到类上的注解
boolean isExist = c.isAnnotationPresent(Boy.class);
if(isExist){
//3.拿到注解实例
Boy d = (Boy)c.getAnnotation(Boy.class);
//访问直接成员的值
System.out.println(d.name());
System.out.println(d.age());
}
//4.找到方法上的注解
Method[] ms = c.getMethods();
for(Method m:ms){
boolean isMExist = m.isAnnotationPresent(Boy.class);
if(isMExist){
Boy d = m.getAnnotation(Boy.class);
System.out.println(d.name());
System.out.println(d.age());
}
}
}
}
getAnnotations()
for(Method m:ms){
Annotation[] as = m.getAnnotations();
for(Annotation a:as){
if(a instanceof Boy){
Boy d = (Boy)a;
System.out.println(d.name());
System.out.println(d.age());
}
@Inherited
如果子类继承 只会继承class上的注解,不会继承方法上的注解