在看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)
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原理