ReflectASM高性能反射Java库
1. 简介#
在日常开发中,经常需要使用反射操作类中的属性或方法。ReflectASM是一个非常小的 Java 库,它提供高性能反射能力。
Github地址:https://github.com/EsotericSoftware/reflectasm
2. 官方性能报告#
3. 用法#
ReflectASM仅可访问public属性和方法。
- pom引入依赖
<dependency>
<groupId>com.esotericsoftware</groupId>
<artifactId>reflectasm</artifactId>
<version>{latest.version}</version>
</dependency>
- 使用 ReflectASM 的构造函数反射:
ConstructorAccess<User> constructorAccess = ConstructorAccess.get(User.class);
User user = constructorAccess.newInstance();
- 使用 ReflectASM 的属性反射:
User user = new User();
FieldAccess fieldAccess = FieldAccess.get(User.class);
fieldAccess.set(user, "username", "张三");
String name = (String) fieldAccess.get(user, "username");
- 使用 ReflectASM 的方法反射:
User user = new User();
MethodAccess methodAccess = MethodAccess.get(User.class);
methodAccess.invoke(user, "setUserame", "张三");
String username = (String) methodAccess.invoke(user, "getUsername");
- 使用 ReflectASM 的属性索引反射(推荐):
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 的方法索引反射(推荐):
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. 单元测试#
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次循环单元测试结果:
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次循环单元测试结果:
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次循环单元测试结果:
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
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理