# hp-reflect **Repository Path**: kkk001/hp-reflect ## Basic Information - **Project Name**: hp-reflect - **Description**: hp-reflect 是一个高性能的反射工具。它使用字节码技术动态生成 access class。通过不同的 access class,可以高效的获取字段的值,或者调用方法,或者生成实例。 在基础框架中非常实用。 - **Primary Language**: Java - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 85 - **Forks**: 27 - **Created**: 2018-08-13 - **Last Updated**: 2025-03-30 ## Categories & Tags **Categories**: utils **Tags**: None ## README # hp-reflect (high performance reflect) #### 项目介绍 hp-reflect 是一个高性能的反射工具。它使用字节码技术动态生成 access class。通过不同的 access class,可以高效的获取字段的值,或者调用方法,或者生成实例。 在基础框架中非常实用。 #### 软件实现 使用 javassist 动态生成 access class,让JDK原生的反射调用可以通过一个具体的实体类来实现直接调用,而不是反射调用,大大提高的反射性能。 举例: 比如我知道一个类 A 的实例 instance 和需要调用的方法名 methodX ,我们使用 JDK 来反射调用的话,会使用如下代码: ```java instance.getClass().getMethod("methodX", xxxType).invoke(instance, xxx); ``` 同样,我也可以通过生成如下的字节码来调用方法 methodX: ```java public class A { public Object methodX(xxxType param) { ...... } public Object methodY(yyyType param) { ...... } } // 利用动态字节码技术生成类似如下类 public class AMethodAccess { public Object invoke(Object instance, String methodName, Object[] params){ A a = (A) instance; switch(methodName) { case "methodX": return a.methodX(params[0]); case "methodY": return a.methodY(params[0]); default: throw new RuntimeException("method not found:" + methodName); } } } // 实际调用 new AMethodAccess().invoke(instance, "methodX"), new Object[]{param}); ``` 沿着这个思路,我们就可以利用 javassist 来动态生成字节码,并实例化出我们想要的 access 类,这样就能像直接调用方法一样来实现反射了。 同理,对类属性 field 和 构造函数 constructor 也可以采用类似的方法来加快反射调用速度。 上面的思想是参考 [RelectASM](https://github.com/EsotericSoftware/reflectasm),不过 RelectASM 是使用 asm 来实现的,且不支持 private 类型的方法和属性的调用。所以这里就使用 javassist 来实现了一把,并且加入扩展了 private 类型的方法和属性的调用,让它更加通用。 #### 使用说明 * 1 调用类方法 ```java MethodAccess methodAccess = MethodAccess.get(fooInstance.getClass()); Object rlt = methodAccess.invoke(fooInstance, "method11", "xxx"); ``` * 2 获取/设置类属性的值 ```java FieldAccess fieldAccess = FieldAccess.get(fooInstance.getClass()); fieldAccess.set(fooInstance, "stringField1", "abc"); ``` * 3 实例化一个类 ```java ConstructorAccess access = ConstructorAccess.get(FooService.class); FooService fooService = access.newInstance(); ```