ReflectASM高性能反射Java库

1. 简介#

  在日常开发中,经常需要使用反射操作类中的属性或方法。ReflectASM是一个非常小的 Java 库,它提供高性能反射能力。
  Github地址:https://github.com/EsotericSoftware/reflectasm

2. 官方性能报告#



3. 用法#

ReflectASM仅可访问public属性和方法。

  • pom引入依赖
Copy
<dependency> <groupId>com.esotericsoftware</groupId> <artifactId>reflectasm</artifactId> <version>{latest.version}</version> </dependency>
  • 使用 ReflectASM 的构造函数反射:
Copy
ConstructorAccess<User> constructorAccess = ConstructorAccess.get(User.class); User user = constructorAccess.newInstance();
  • 使用 ReflectASM 的属性反射:
Copy
User user = new User(); FieldAccess fieldAccess = FieldAccess.get(User.class); fieldAccess.set(user, "username", "张三"); String name = (String) fieldAccess.get(user, "username");
  • 使用 ReflectASM 的方法反射:
Copy
User user = new User(); MethodAccess methodAccess = MethodAccess.get(User.class); methodAccess.invoke(user, "setUserame", "张三"); String username = (String) methodAccess.invoke(user, "getUsername");
  • 使用 ReflectASM 的属性索引反射(推荐):
Copy
User user = new User(); FieldAccess fieldAccess = FieldAccess.get(User.class); int index = fieldAccess.getIndex("username"); fieldAccess.set(user, index, "张三"); String username = (String) fieldAccess.get(user, index);
  • 使用 ReflectASM 的方法索引反射(推荐):
Copy
User user = new User(); MethodAccess methodAccess = MethodAccess.get(User.class); int setIndex = methodAccess.getIndex("setUserame"); int getIndex = methodAccess.getIndex("getUsername"); methodAccess.invoke(user, setIndex, "张三" String username = (String) methodAccess.invoke(user, getIndex);

4. 单元测试#

Copy
import com.esotericsoftware.reflectasm.ConstructorAccess; import com.esotericsoftware.reflectasm.FieldAccess; import com.esotericsoftware.reflectasm.MethodAccess; import lombok.extern.slf4j.Slf4j; import org.junit.jupiter.api.Test; import org.springframework.util.StopWatch; import java.lang.reflect.Method; /** * 高性能反射Java库 单元测试 * * @author CL */ @Slf4j public class ReflectAsmTest { /** * 测试方案:循环 n 次,通过set方法设置值,然后通过get方法获取值<br/> */ @Test public void test() throws Exception { // final String FIELD_NAME = "username"; final String SET_METHOD_NAME = "setUsername"; final String GET_METHOD_NAME = "getUsername"; // 次数 int n = 1_0000; StopWatch stopWatch = new StopWatch(); stopWatch.start("Java反射"); Class<User> clazz = User.class; // Field field = clazz.getDeclaredField(FIELD_NAME); // field.setAccessible(true); Method setMethod = clazz.getDeclaredMethod(SET_METHOD_NAME, String.class); Method getmethod = clazz.getDeclaredMethod(GET_METHOD_NAME); for (int i = 1; i <= n; i++) { User user = clazz.newInstance(); setMethod.invoke(user, "方法" + i); Object invoke = getmethod.invoke(user); // log.debug("get值:{}", invoke); } stopWatch.stop(); stopWatch.start("ReflectAsm反射"); ConstructorAccess<User> constructorAccess = ConstructorAccess.get(User.class); FieldAccess fieldAccess = FieldAccess.get(User.class); MethodAccess methodAccess = MethodAccess.get(User.class); for (int i = 1; i <= n; i++) { User user = constructorAccess.newInstance(); methodAccess.invoke(user, SET_METHOD_NAME, "方法" + i); Object invoke = methodAccess.invoke(user, GET_METHOD_NAME); // log.debug("get值:{}", invoke); } stopWatch.stop(); stopWatch.start("ReflectAsm反射(优化)"); int setIndex = methodAccess.getIndex(SET_METHOD_NAME); int getIndex = methodAccess.getIndex(GET_METHOD_NAME); for (int i = 1; i <= n; i++) { User user = constructorAccess.newInstance(); methodAccess.invoke(user, setIndex, "方法" + i); Object invoke = methodAccess.invoke(user, getIndex); // log.debug("get值:{}", invoke); } stopWatch.stop(); for (StopWatch.TaskInfo taskInfo : stopWatch.getTaskInfo()) { log.info("{} 耗时:{} ms", taskInfo.getTaskName(), taskInfo.getTimeMillis()); } } } class User { private String username; public User() { } public User(String username) { this.username = username; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } }

  100次循环单元测试结果:

Copy
23:54:37.630 [main] INFO com.c3stones.reflectasm.ReflectAsmTest - Java反射 耗时:3 ms 23:54:37.635 [main] INFO com.c3stones.reflectasm.ReflectAsmTest - ReflectAsm反射 耗时:21 ms 23:54:37.635 [main] INFO com.c3stones.reflectasm.ReflectAsmTest - ReflectAsm反射(优化) 耗时:0 ms

  1000次循环单元测试结果:

Copy
23:55:07.161 [main] INFO com.c3stones.reflectasm.ReflectAsmTest - Java反射 耗时:7 ms 23:55:07.168 [main] INFO com.c3stones.reflectasm.ReflectAsmTest - ReflectAsm反射 耗时:35 ms 23:55:07.168 [main] INFO com.c3stones.reflectasm.ReflectAsmTest - ReflectAsm反射(优化) 耗时:1 ms

  10000次循环单元测试结果:

Copy
23:55:27.604 [main] INFO com.c3stones.reflectasm.ReflectAsmTest - Java反射 耗时:44 ms 23:55:27.611 [main] INFO com.c3stones.reflectasm.ReflectAsmTest - ReflectAsm反射 耗时:49 ms 23:55:27.611 [main] INFO com.c3stones.reflectasm.ReflectAsmTest - ReflectAsm反射(优化) 耗时:7 ms
posted @   C3Stones  阅读(971)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
点击右上角即可分享
微信分享提示
CONTENTS