java魔法类之ReflectionFactory介绍
前言
在看objenesis(一个提供多种实例化对象的方式的库)的源码时,发现其中使用到了ReflectionFactory类,它会绕过构造器来实例化对象,且会跳过类成员变量的初始化。
简单使用
使用反射实例化对象
import java.lang.reflect.Constructor;
public class TestReflection {
public static void main(String[] args) throws Exception {
Constructor<User> declaredConstructor = User.class.getDeclaredConstructor();
System.out.println(declaredConstructor.newInstance());
}
public static class User {
private String name = "lisi";
public User() {
System.out.println("User created");
}
@Override
public String toString() {
return "user=" + name;
}
}
}
输出结果为
User created
user=lisi
使用ReflectionFactory实例化对象(java8)
import sun.reflect.ReflectionFactory;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
public class TestReflectionFactory {
public static void main(String[] args)
throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
//获取ReflectionFactory对象,它本身是单例的
ReflectionFactory reflectionFactory = ReflectionFactory.getReflectionFactory();
//获取Object类的构造器
Constructor<Object> constructor = Object.class.getDeclaredConstructor();
//根据Object构造器创建一个User类的构造器
Constructor<?> constructorForSerialization = reflectionFactory
.newConstructorForSerialization(User.class, constructor);
constructorForSerialization.setAccessible(true);
//实例化对象
System.out.println(constructorForSerialization.newInstance());
}
public static class User {
private String name = "lisi";
public User() {
System.out.println("User created");
}
@Override
public String toString() {
return "user=" + name;
}
}
}
输出结果为
user=null
可以看到正常实例化了对象,但没有执行构造器且name成员变量没有被初始化。
使用ReflectionFactory实例化对象(java11)
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class TestReflectionFactory {
public static void main(String[] args) throws InvocationTargetException, InstantiationException, IllegalAccessException, NoSuchMethodException, ClassNotFoundException {
Constructor<?> constructor = newConstructorForSerialization(User.class, getJavaLangObjectConstructor());
System.out.println(constructor.newInstance());
}
public static class User {
private String name = "lisi";
public User() {
System.out.println("User created");
}
@Override
public String toString() {
return "user=" + name;
}
}
public static <T> Constructor<T> newConstructorForSerialization(Class<T> type, Constructor<?> constructor) throws ClassNotFoundException, InvocationTargetException, NoSuchMethodException, IllegalAccessException {
Class<?> reflectionFactoryClass = getReflectionFactoryClass();
Object reflectionFactory = createReflectionFactory(reflectionFactoryClass);
Method newConstructorForSerializationMethod = getNewConstructorForSerializationMethod(reflectionFactoryClass);
return (Constructor) newConstructorForSerializationMethod.invoke(reflectionFactory, type, constructor);
}
private static Class<?> getReflectionFactoryClass() throws ClassNotFoundException {
return Class.forName("sun.reflect.ReflectionFactory");
}
private static Object createReflectionFactory(Class<?> reflectionFactoryClass) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
Method method = reflectionFactoryClass.getDeclaredMethod("getReflectionFactory");
return method.invoke((Object) null);
}
private static Method getNewConstructorForSerializationMethod(Class<?> reflectionFactoryClass) throws NoSuchMethodException {
return reflectionFactoryClass.getDeclaredMethod("newConstructorForSerialization", Class.class, Constructor.class);
}
private static Constructor<Object> getJavaLangObjectConstructor() throws NoSuchMethodException {
return Object.class.getConstructor((Class[]) null);
}
}
输出结果为
user=null
通过反射来获取ReflectionFactory类(参考Spring源码SunReflectionFactoryInstantiator类)。
实现原理
内部使用字节码创建ConstructorAccessor接口的实现类
public final Constructor<?> newConstructorForSerialization(Class<?> cl,
Constructor<?> constructorToCall)
{
if (constructorToCall.getDeclaringClass() == cl) {
constructorToCall.setAccessible(true);
return constructorToCall;
}
return generateConstructor(cl, constructorToCall);
}
// 创建构造器
private final Constructor<?> generateConstructor(Class<?> cl,
Constructor<?> constructorToCall) {
//核心逻辑,通过字节码生成ConstructorAccessor,实现类类型为SerializationConstructorAccessorImpl
ConstructorAccessor acc = new MethodAccessorGenerator().
generateSerializationConstructor(cl,
constructorToCall.getParameterTypes(),
constructorToCall.getExceptionTypes(),
constructorToCall.getModifiers(),
constructorToCall.getDeclaringClass());
Constructor<?> c = newConstructor(constructorToCall.getDeclaringClass(),
constructorToCall.getParameterTypes(),
constructorToCall.getExceptionTypes(),
constructorToCall.getModifiers(),
langReflectAccess().
getConstructorSlot(constructorToCall),
langReflectAccess().
getConstructorSignature(constructorToCall),
langReflectAccess().
getConstructorAnnotations(constructorToCall),
langReflectAccess().
getConstructorParameterAnnotations(constructorToCall));
setConstructorAccessor(c, acc);
c.setAccessible(true);
return c;
}
生成字节码的核心为MethodAccessorGenerator的generateSerializationConstructor()方法。
参考
objenesis官网
reflectionFactory.newConstructorForSerialization原理