ReflectASM 使用字节码生成的方式实现了更为高效的反射机制。执行时会生成一个存取类来 set/get 字段,访问方法或创建实例。一看到 ASM 就能领悟到 ReflectASM 会用字节码生成的方式,而不是依赖于 Java 本身的反射机制来实现的,所以它更快,并且避免了访问原始类型因自动装箱而产生的问题。

<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 {
    
    public static void main(String[] args) throws Exception{
        AppTest test = new AppTest();
        test.testJdkReflect();
        test.testReflectAsm4Name();
        test.testReflectAsm4Index();
    }
    
    /**
     * JDK反射调用方法
     * @throws Exception
     */
    @Test
    public void testJdkReflect() throws Exception {
        UserService target = new UserService();
        long start = System.currentTimeMillis();
        Method method = target.getClass().getMethod("update", int.class, String.class);
        for (int i = 0; i < 100000000; i++) {
            method.invoke(target, 1, "zhangsan");
        }
        long end = System.currentTimeMillis();
        System.out.println("timeout=" + (end - start));//809 753 880 875 816 
    }

    /**
     * ReflectAsm反射调用方法
     * 用名称定位反射方法
     */
    @Test
    public void testReflectAsm4Name() {
        UserService target = new UserService();
        MethodAccess access = MethodAccess.get(UserService.class);//生成字节码的方式创建UserServiceMethodAccess
        long start = System.currentTimeMillis();
        for (int i = 0; i < 100000000; i++) {
            access.invoke(target, "update", 1, "zhangsan");
        }
        long end = System.currentTimeMillis();
        System.out.println("timeout=" + (end - start));//523 382 415 489 482
    }

    /**
     * ReflectAsm反射调用方法
     * 用方法和字段的索引定位反射方法,性能高
     */
    @Test
    public void testReflectAsm4Index() {
        UserService target = 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(target, 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);
    }

}