Java高性能反射工具包ReflectASM
阿新 • • 發佈:2017-10-24
自動裝箱 class spa hang out 字段值 並且 get title
ReflectASM 使用字節碼生成的方式實現了更為高效的反射機制。執行時會生成一個存取類來 set/get 字段,訪問方法或創建實例。一看到 ASM 就能領悟到 ReflectASM 會用字節碼生成的方式,而不是依賴於 Java 本身的反射機制來實現的,所以它更快,並且避免了訪問原始類型因自動裝箱而產生的問題。
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.jts</groupId> <artifactId>t1</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.10</version> <scope>test</scope> </dependency> <dependency> <groupId>com.esotericsoftware</groupId> <artifactId>reflectasm</artifactId> <version>1.11.0</version> </dependency> </dependencies> </project>
待反射的類:
package com.jts.service; public class UserService { public int state; public void update(int id, String username) { } }
測試類:
package com.jts.test; import java.lang.reflect.Method; import org.junit.Test; import com.esotericsoftware.reflectasm.ConstructorAccess; import com.esotericsoftware.reflectasm.FieldAccess; import com.esotericsoftware.reflectasm.MethodAccess; import com.jts.service.UserService; public class AppTest { /** * JDK反射調用方法 * @throws Exception */ @Test public void testJdkReflect() throws Exception { UserService userService = new UserService(); long start = System.currentTimeMillis(); Method method = userService.getClass().getMethod("update", int.class, String.class); for (int i = 0; i < 100000000; i++) { method.invoke(userService, 1, "zhangsan"); } long end = System.currentTimeMillis(); System.out.println("timeout=" + (end - start));//809 753 880 875 816 } /** * ReflectAsm反射調用方法 * 用名稱定位反射方法 */ @Test public void testReflectAsm4Name() { UserService userService = new UserService(); MethodAccess access = MethodAccess.get(UserService.class);//生成字節碼的方式創建UserServiceMethodAccess long start = System.currentTimeMillis(); for (int i = 0; i < 100000000; i++) { access.invoke(userService, "update", 1, "zhangsan"); } long end = System.currentTimeMillis(); System.out.println("timeout=" + (end - start));//523 382 415 489 482 } /** * ReflectAsm反射調用方法 * 用方法和字段的索引定位反射方法,性能高 */ @Test public void testReflectAsm4Index() { UserService userService = new UserService(); MethodAccess access = MethodAccess.get(UserService.class); int index = access.getIndex("update", int.class, String.class); long start = System.currentTimeMillis(); for (int i = 0; i < 100000000; i++) { access.invoke(userService, index, 1, "zhangsan"); } long end = System.currentTimeMillis(); System.out.println("timeout=" + (end - start));//12 15 23 14 24 } /** * ReflectAsm反射來set/get字段值 */ @Test public void testFieldAccess() { UserService target = new UserService(); FieldAccess fieldAccess = FieldAccess.get(target.getClass()); fieldAccess.set(target, "state", 1); int state = (Integer)fieldAccess.get(target, "state"); System.out.println(state); } /** * ReflectAsm反射來調用構造方法 */ @Test public void testConstructorAccess() { ConstructorAccess<UserService> constructorAccess = ConstructorAccess.get(UserService.class); UserService userService = constructorAccess.newInstance(); System.out.println(userService); } /** * 查找方法的索引 */ @Test public void testIndex() { UserService target = new UserService(); MethodAccess methodAccess = MethodAccess.get(target.getClass()); int index = methodAccess.getIndex("update", int.class, String.class); System.out.println(index); } }
Java高性能反射工具包ReflectASM