在项目开发中我们经常会使用到放射,但是反射存在一个问题,就是速度不够快。这里来探究一下反射不够快的原因。
首先我们先写这样的一个测试类。
package com.chen;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class ReflectTest {
static Long beforeTime;
static Long currentTime;
static final int CYCLE = (int) 1e8;
static class NumberTest {
private int number;
public int getNumber() {
return this.number;
}
public void setNumber(int number) {
this.number = number;
}
}
public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
NumberTest numberTest = new NumberTest();
Class<? extends NumberTest> clazz = numberTest.getClass();
startTest();
for (int i = 0; i < CYCLE; i++) {
Method getNumber = clazz.getMethod("getNumber");
getNumber.setAccessible(true);
getNumber.invoke(numberTest);
}
showTime("反射关闭安全检查");
for (int i = 0; i < CYCLE; i++) {
Method getNumber = clazz.getMethod("getNumber");
getNumber.invoke(numberTest);
}
showTime("反射获取方法");
for (int i = 0; i < CYCLE; i++) {
numberTest.getNumber();
}
showTime("普通get方法");
Method getNumber = null;
for (int i = 0; i < CYCLE; i++) {
if(getNumber == null){
getNumber = clazz.getMethod("getNumber");
}
getNumber.invoke(numberTest);
}
showTime("反射加缓存get方法");
Method getNumber1 = null;
for (int i = 0; i < CYCLE; i++) {
if(getNumber1 == null){
getNumber1 = clazz.getMethod("getNumber");
getNumber1.setAccessible(true);
}
getNumber1.invoke(numberTest);
}
showTime("反射加缓存关闭安全检查get方法");
}
public static void startTest() {
beforeTime = System.currentTimeMillis();
}
public static void showTime(String prefix) {
currentTime = System.currentTimeMillis();
System.out.printf("%s-花费时间: %d ms%n", prefix, currentTime - beforeTime);
beforeTime = currentTime;
}
}
在运行后我们发现
- 关闭安全检查后我们的反射执行方法的速度变快了
- 通过缓存我们的method对象 我们的执行速度变快了
反射提高运行速度方面,可以明显的感觉到,缓存对象是提高效率的一个很有效的方法。运行速度提高了上百倍。