自定义注解
注解定义的关键字:@interface
自定义注解中的成员属性
- 修饰符 数据类型 属性名(); public abstract
- 数据类型的要求:
- 可以是所有的基本数据类型
- 可以是字符串类型
- 可以是枚举类型
- 可以是Class类
- 可以是其它的注解类型
- 或者是以上类型的一维数组
public @interface MyAnnotation {
//定义注解的属性
String name ();//字符串类型
int age(); //基本类型int
Color color();//枚举类型
Class clazz();//Class类型
String[] value();//字符串数组
}
注解的属性赋值
- @注解名(属性=值,属性=值)
@Book(name = "红楼梦",price = 50.99,jieShao = "金陵十二钗",author = {"曹雪芹","高鹗"})
public void sellBook(){
}
- 注解中有默认值,可以不用赋值
//页数,默认值200
int page() default 200;
@Book(page = 300,name = "红楼梦",price = 50.99,jieShao = "金陵十二钗",author = {"曹雪芹","高鹗"})
public void sellBook(){
}
- 注解中的属性只有一个,属性值必须是value,可以不写属性名
- 如果是一个数组,数组中的元素只有一个,可以不写{}
@NewsPaper({"新闻早知道","新闻晚知道","新闻不知道"})
public void sellNewPaper(){
}
注解赋值的注意事项:一个注解,在一个对象上只能使用一次
注解解析
获取注解中的属性值,注解解析必须使用反射
public class CarStore {
@Car(name = "比亚迪",price = 89999)
public void sellCar(){
}
}
反射方法sellCar(),获取方法上的注解
-
Method类,表示成员方法对象,类实现接口AnnotatedElement
-
接口中的方法:isAnnotationPresent(Class c)判断方法上是否有注解,有注解返回true,没有注解返回false.
- 参数Class对象,传递注解的class文件对象
-
/** * 反射获取方法上的注解 */ @Test public void testAnnotation()throws Exception{ Class clazz = Class.forName("com.atguigu.annotation.CarStore"); //反射获取方法sellCar Method method = clazz.getMethod("sellCar"); System.out.println("method = " + method); //接口中的方法:isAnnotationPresent(Class c)判断方法上是否有注解, // 有注解返回true,没有注解返回false. boolean b = method.isAnnotationPresent(Car.class); System.out.println("b = " + b); //接口方法,获取注解 Car car = method.getAnnotation(Car.class); //获取注解的属性 String name = car.name(); double price = car.price(); System.out.println("name = " + name); System.out.println("price = " + price); }
接口中的方法:getAnnotation(Class对象)获取注解
元注解
JDK内置了2个元注解
- @Target注解:明确其它注解可以出现的位置
- 不是用该注解,我们自定义的注解@Car,可以出现在一个类的任意位置上
- @Target控制我们自己的注解
- @Target注解的属性是value,数据类型ElementType
- ElementType是枚举:静态成员
- TYPE,METHOD,FIELD指示我们的注解,可以出现在类上,方法上,成员变量上
//使用元注解,Car注解出现在方法上,类上
@Target(value = {ElementType.METHOD,ElementType.TYPE})
public @interface Car {
String name();
double price();
}
- @Retention注解:明确其它注解生存的时间
- 注解属性是value,数据类型RetentionPolicy
- RetentionPolicy是枚举:
- SOURCE,CLASS,RUNTIME 当前的注解存在时间,源码中,class文件中,运行的内存中
- SOURCE:当我们将java代码编译成class文件时,该注解被遗弃
- CLASS:默认的,注解保留在class文件中,当jvm把class文件加载到内存中时被遗弃
- RUNTIME:注解不仅能保存在class文件中,也能保存在内存中
//SOURCE 我们的Override就是使用这个,在编译期间生效
//使用元注解,Car注解出现在方法上,类上
@Target(value = {ElementType.METHOD,ElementType.TYPE})
//使用 元注解,Car注解,生存到内存中
@Retention(value = RetentionPolicy.RUNTIME)
public @interface Car {
String name();
double price();
}