1. 简介
在日常开发中,经常需要使用反射操作类中的属性或方法。ReflectASM是一个非常小的 Java 库,它提供高性能反射能力。
Github地址:https://github.com/EsotericSoftware/reflectasm
2. 官方性能报告
3. 用法
ReflectASM仅可访问public属性和方法。
- pom引入依赖
com.esotericsoftware
reflectasm
{latest.version}
- 使用 ReflectASM 的构造函数反射:
ConstructorAccess 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方法获取值
*/
@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 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 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