自定义注解(理解)
注解属性:
注解本质就是一个接口,接口中可以有常量和抽象方法
抽象方法在注解中就称之为注解属性
注解属性类型:
基本类型
String
Class
Annotation
Enum:枚举
以上类型对应的一维数组
注意:
一旦注解有属性了,使用注解的时候必须赋值,(除非这个注解属性有默认值)
赋值的格式:
@注解名(属性名=属性值)
若注解类型为数组,且只有一个值的时候,可以有两种写法
方式1:
属性名 = { 值 }
方式2:
属性名=属性值
若属性名为value的时候,且只需要为这个value属性赋值的时候,value可以省略
元注解:(理解)
定义在注解上的注解
@Retention 规定注解保留到什么阶段 值为RetentionPolicy的三个枚举值
SOURCE:只在代码中保留,在字节码文件中就删除了
CLASS:在代码和字节码文件中保留
RUNTIME:所有阶段都保留
@Target 规定注解作用在什么上面 值为ElementType的枚举值
TYPE:作用在类 接口 等上面
METHOD:作用方法上面
注解属性:
注解本质就是一个接口,接口中可以有常量和抽象方法
抽象方法在注解中就称之为注解属性
注解属性类型:
基本类型
String
Class
Annotation
Enum:枚举
以上类型对应的一维数组
注意:
一旦注解有属性了,使用注解的时候必须赋值,(除非这个注解属性有默认值)
赋值的格式:
@注解名(属性名=属性值)
若注解类型为数组,且只有一个值的时候,可以有两种写法
方式1:
属性名 = { 值 }
方式2:
属性名=属性值
若属性名为value的时候,且只需要为这个value属性赋值的时候,value可以省略
元注解:(理解)
定义在注解上的注解
@Retention 规定注解保留到什么阶段 值为RetentionPolicy的三个枚举值
SOURCE:只在代码中保留,在字节码文件中就删除了
CLASS:在代码和字节码文件中保留
RUNTIME:所有阶段都保留
@Target 规定注解作用在什么上面 值为ElementType的枚举值
TYPE:作用在类 接口 等上面
METHOD:作用方法上面
FIELD:作用字段上面
代码实现:
首先,自定义一个注解
package com.itheima.a_annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
//注解在运行时保留
@Retention(RetentionPolicy.RUNTIME)
//注解只能作用在方法上
@Target(ElementType.METHOD)
public @interface MyTest {
}
其次,创建一个测试类,使用自定义注解
package com.itheima.a_annotation;
public class MyTestTest {
@MyTest
public void f1(){
System.out.println("f1方法执行了~~~~");
}
public void f2(){
System.out.println("f2方法执行了~~~~");
}
@MyTest
public void f3(){
System.out.println("f3方法执行了~~~~");
}
}
最后,利用反射的方式获取该注解类对象,让带有该注解的方法运行。
package com.itheima.a_annotation;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class MainTest {
public static void main(String[] args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, InstantiationException {
//运行这个类的时候 需要将 测试类中带有@mytest所有方法执行
//获取字节码对象
Class clazz=MyTestTest.class;
//获取所有的方法
Method[] arr = clazz.getMethods();
//让带有注解的方法执行
for (Method m : arr) {
//获取有注解的方法
//判断方法是否有指定的注解
boolean flag=m.isAnnotationPresent(MyTest.class);
if(flag){
//System.out.println(m.getName());
m.invoke(clazz.newInstance());
}
}
}
}