反射虽然强大,但存在性能的不足,使用反射基本上是一种解释操作,您可以告诉JVM您希望做什么并且它满足您的要求。曾经看过一本书举例说调用同一个方法,使用反射来动态实现比直接在源代码中编写的方式大概慢一到两个数量级。或许方法比较快些,但经过测试发现字段更慢。
测试Demo如下:
- package net.oseye;
- import java.lang.reflect.Field;
- public class ReflectTest {
- //直接调用
- public static int numAdd(int loops){
- int val=0;
- long startTime=0;
- for(int i=0;i<loops;i++){
- if(i==0){startTime=System.nanoTime();}
- val+=i;
- }
- long totalTime=System.nanoTime()-startTime;
- System.out.println("直接调用总的纳秒时间:\t\t"+totalTime);
- return val;
- }
- //引用调用字段
- public static int numAddReference(int loops){
- User user=new User();
- long startTime=0;
- for(int i=0;i<loops;i++){
- if(i==0){startTime=System.nanoTime();}
- user.num+=i;
- }
- long totalTime=System.nanoTime()-startTime;
- System.out.println("引用调用字段总的纳秒时间:\t"+totalTime);
- return user.num;
- }
- //反射调用字段
- public static int numAddReflection(int loops) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException{
- User user=new User();
- long startTime=0;
- for(int i=0;i<loops;i++){
- if(i==0){startTime=System.nanoTime();}
- Class<?> cUser=user.getClass();
- Field field=cUser.getField("num");
- field.set(user, field.getInt(user)+i);
- }
- long totalTime=System.nanoTime()-startTime;
- System.out.println("反射调用字段总的纳秒时间:\t"+totalTime);
- return user.num;
- }
- public static void main(String[] args) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException{
- int loops=1000000;
- numAdd(loops);
- numAddReference(loops);
- numAddReflection(loops);
- }
- }
- class User{
- public int num;
- }
输出:
- 直接调用总的纳秒时间: 4784726
- 引用调用字段总的纳秒时间: 26341772
- 反射调用字段总的纳秒时间: 2707670627
测试100万次,除掉第一次的时间,可以看出反射用的时间是引用的100倍,是直接调用的500多倍。当然根据测试的次数不同,机器的配置不同,结果稍有不同