Java教程

java魔法类之ReflectionFactory介绍

本文主要是介绍java魔法类之ReflectionFactory介绍,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

前言

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

这篇关于java魔法类之ReflectionFactory介绍的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!