java注解与反射

一、什么是注解?

注解的定义

代码中的特殊标记,这些标记可以在编译、类加载、运行时被读取,并执行相对应的处理。

元注解

元注解就是用来修饰注解的。即:@interface上面按需要注解上一些东西,包括但不限 @Retention、@Target、@Document、@Inherited四种。

  1. @Retention 注解的保留策略:

    • @Retention(RetentionPolicy.SOURCE) // 注解仅存在于源码中,在class字节码文件中不包含
    • @Retention(RetentionPolicy.CLASS) // 默认的保留策略,注解会在class字节码文件中存在,但运行时无法获得
    • @Retention(RetentionPolicy.RUNTIME) // 注解会在class字节码文件中存在,在运行时可以通过反射获取到
  2. @Target注解的作用目标:

    • @Target(ElementType.TYPE) // 接口、类、枚举、注解
    • @Target(ElementType.FIELD) // 字段、枚举的常量
    • @Target(ElementType.METHOD) // 方法
    • @Target(ElementType.PARAMETER) // 方法参数
    • @Target(ElementType.CONSTRUCTOR) // 构造函数
    • @Target(ElementType.LOCAL_VARIABLE) // 局部变量
    • @Target(ElementType.ANNOTATION_TYPE) // 注解
    • @Target(ElementType.PACKAGE) // 包
  3. @Documented 注解包含在javadoc中:

  4. @Inherited 注解可以被继承

二、注解的使用在什么地方

  1. java 内置注解
    1. @Override
    2. @Deprecated
    3. @SuppressWarnings
  2. 框架中@Bean @Autowired 、@Service、 @Controller、@Repository ...等,lombok 中 @Data、 @AllArgsConstructor等

注解实践?

自定义注解:

//todo: code
  1. aop + 自定义注解
    使用@Diff 注解实现方法级别比对,详见:文章(重构最佳实践工具@diff框架)

  2. 注解
    lombok 原理,会在javac 编译时,在编译期时把 Lombok 的注解代码,转换为常规的 Java 方法

反射

什么是反射?

反射就是Java可以给我们在运行时获取类(Class)的信息。

获取Class对象

获取Class 对象的四种方式:

  1. 通过类.class 获取
Class userClass = User.class;
  1. 通过 Class.forName()传入类的全路径获取:
Class c1 = Class.forName("demo.base.reflection.User");
  1. 通过对象实例instance.getClass()获取:
User o = new User();
Class userClass = o.getClass();
  1. 通过类加载器xxxClassLoader.loadClass()传入类路径获取:
ClassLoader.getSystemClassLoader().loadClass("cn.javaguide.TargetObject");

常见api

  1. 获取属性
 Field[] fields = calssA.getFields(); //获得public属性
 Field[] allFields = calssA.getDeclaredFields(); //获取全部属性(包含私有属性)
  1. 获取方法
Method[] methods = c1.getMethods(); //获得本类和父类的public方法
methods = c1.getDeclaredMethods();  //获得本类的全部方法
  1. 获取指定方法
Method methodName = c1.getDeclaredMethod("setSpecialName", null);
Method methodName02 = c1.getDeclaredMethod("setName", String.class);
  1. 获取构造器
Constructor[] constructors = c1.getConstructors(); //获取public方法
constructors = c1.getDeclaredConstructors();    //获取全部方法
  1. 获取注解
Annotation[] annotations = c1.getAnnotations();
 annotations = c1.getDeclaredAnnotations();

6方法调用 invoke()

 Class c1 = Class.forName("demo.base.reflection.User");
 Method setName = c1.getDeclaredMethod("setName", String.class);
 setName.invoke(user3, "jacky");

7.安全检查关闭,以提升反射速度

method.setAccessible(true)
method.invoke(user3, "jacky");

反射的应用

1.列如jdk的动态代理等

2.自定义注解 + aop切面 + 反射
详见:[文章链接todo]. 通过反射获取目标类,调用目标方法得到结果,并通过groovy配置diff配置。

posted @ 2025-02-14 17:49  执大象  阅读(13)  评论(0)    收藏  举报