反射、注解与动态代理

一、反射

1.1 认识反射

  • 定义:反射是指在程序运行过程中动态获取类的成员(成员变量、成员方法、构造方法)并使用。

  • 作用:可以在运行时动态地操作类及其成员。

1.2 获取Class类的对象

  • 方式一Class.forName("全类名"),返回指定类的Class对象。

  • 方式二类名.class,直接获取类的Class对象。

  • 方式三对象.getClass(),通过对象获取其对应的Class对象。

1.3 获取类的构造方法

  • 方法

    • getConstructors():获取所有public构造方法。

    • getDeclaredConstructors():获取所有构造方法(包括私有)。

    • getConstructor(Class... parameterTypes):获取指定参数类型的public构造方法。

    • getDeclaredConstructor(Class... parameterTypes):获取指定参数类型的构造方法(无视访问权限)。

  • 使用:通过构造方法对象调用newInstance()创建对象,私有构造方法需调用setAccessible(true)

1.4 获取类的成员变量

  • 方法

    • getFields():获取所有public成员变量。

    • getDeclaredFields():获取所有成员变量(包括私有)。

    • getField(String name):获取指定名称的public成员变量。

    • getDeclaredField(String name):获取指定名称的成员变量(无视访问权限)。

  • 操作:通过Field对象调用set(Object obj, Object value)赋值,调用get(Object obj)获取值,私有成员变量需调用setAccessible(true)

1.5 获取类的成员方法

  • 方法

    • getMethods():获取所有public方法。

    • getDeclaredMethods():获取所有方法(包括私有)。

    • getMethod(String name, Class... parameterTypes):获取指定参数类型的public方法。

    • getDeclaredMethod(String name, Class... parameterTypes):获取指定参数类型的方法(无视访问权限)。

  • 使用:通过Method对象调用invoke(Object obj, Object... args)执行方法,私有方法需调用setAccessible(true)

1.6 反射的作用与应用场景

  • 作用

    • 动态获取类的成员信息。

    • 动态调用类的方法。

    • 破坏封装性(通过setAccessible(true))。

  • 应用场景

    • 实现通用框架(如Spring的依赖注入)。

    • 模拟Junit框架。

    • 动态代理。


二、注解

2.1 概述与自定义注解

  • 定义:注解是JDK 5引入的一种元数据机制,用于为代码提供额外的信息。

  • 自定义注解

    • 使用@interface定义注解。

    • 注解中的方法默认返回类型为String,可指定默认值。

    • 属性支持基本类型、String、枚举、Class、注解及它们的数组。

2.2 元注解

  • @Target:指定注解的使用范围(如TYPEMETHODFIELD等)。

  • @Retention:指定注解的生命周期(SOURCECLASSRUNTIME)。

  • @Documented:表示注解将被包含在JavaDoc中。

  • @Inherited:表示注解可以被继承。

2.3 注解的解析

  • 方法

    • getDeclaredAnnotations():获取对象上的所有注解。

    • getDeclaredAnnotation(Class annotationClass):获取指定类型的注解。

    • isAnnotationPresent(Class annotationClass):判断是否包含指定注解。

  • 解析对象:通过ClassMethodField等对象解析注解。

2.4 应用场景

  • 模拟Junit框架:通过注解标记测试方法,并在运行时解析注解执行测试。

  • 日志记录:通过注解记录方法的执行日志。


三、动态代理

3.1 概述与入门

  • 定义:动态代理是一种在运行时动态生成代理对象的技术,用于增强原始对象的功能。

  • 实现方式:通过java.lang.reflect.Proxy类生成代理对象。

3.2 实现动态代理

  • 步骤

    1. 定义接口,原始类和代理类实现相同接口。

    2. 创建原始类对象。

    3. 使用Proxy.newProxyInstance()生成代理对象。

    4. 通过代理对象调用方法。

  • 方法

    • Proxy.newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h)

      • ClassLoader:类加载器。

      • interfaces:代理类实现的接口数组。

      • InvocationHandler:调用处理器,用于处理代理对象的方法调用。

3.3 应用案例

  • 模拟企业业务功能:通过动态代理实现功能增强,如性能统计、日志记录等。


思维导图

以下是根据上述内容整理的思维导图:

plaintext复制


├── 一、反射
│   ├── 1.1 认识反射
│   ├── 1.2 获取Class对象
│   ├── 1.3 获取构造方法
│   ├── 1.4 获取成员变量
│   ├── 1.5 获取成员方法
│   └── 1.6 反射的作用与应用场景
├── 二、注解
│   ├── 2.1 概述与自定义注解
│   ├── 2.2 元注解
│   ├── 2.3 注解的解析
│   └── 2.4 应用场景
├── 三、动态代理
│   ├── 3.1 概述与入门
│   ├── 3.2 实现动态代理
│   └── 3.3 应用案例

你可能感兴趣的:(java,jvm,算法)