前言
在看objenesis(一个提供多种实例化对象的方式的库)的源码时,发现其中使用到了ReflectionFactory类,通过它可以绕过构造器来实例化对象。
简单使用
定义一个包含有参构造器的类
public class User {
private String name;
public User(String name) {
System.out.println("User.Constructor");
}
@Override
public String toString() {
return "User.toString()";
}
}
使用反射实例化对象
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());
}
}
会报错,因为没有无参的构造器
Exception in thread "main" java.lang.NoSuchMethodException: com.imooc.sourcecode.java.objenesis.test1.User.<init>()
at java.base/java.lang.Class.getConstructor0(Class.java:3350)
at java.base/java.lang.Class.getDeclaredConstructor(Class.java:2554)
at com.imooc.sourcecode.java.objenesis.test1.TestReflection.main(TestReflection.java:9)
使用ReflectionFactory实例化对象
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import sun.reflect.ReflectionFactory;
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());
}
}
输出结果为
User.toString()
可以看到正常实例化了对象并且没有执行构造器。
实现原理
内部使用字节码创建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原理