概述
简介
Objenesis是一个Java的库,主要用来创建特定的对象。
由于不是所有的类都有无参构造器又或者类构造器是private,在这样的情况下,如果我们还想实例化对象,class.newInstance是无法满足的。
使用
public class Test {
private int i;
public Test(int i){
this.i = i;
}
public void show(){
System.out.println("test..." + i);
}
public static void main(String[] args) {
Objenesis objenesis = new ObjenesisStd(true);
Test test = objenesis.newInstance(Test.class);
test.show();
}
}
使用非常简单,运行后可以看到控制台打印出test...0
实现
1. new ObjenesisStd
Objenesis由子类ObjenesisObjenesisStd实现,构造方法中使用了缓存并且创建了StdInstantiatorStrategy对象
public ObjenesisStd(boolean useCache) { super(new StdInstantiatorStrategy(), useCache); }
ObjenesisBase初始化strategy,创建ConcurrentHashMap存放缓存对象
protected final InstantiatorStrategy strategy; protected ConcurrentHashMap<String, ObjectInstantiator<?>> cache; public ObjenesisBase(InstantiatorStrategy strategy, boolean useCache) { if (strategy == null) { throw new IllegalArgumentException("A strategy can't be null"); } else { this.strategy = strategy; this.cache = useCache ? new ConcurrentHashMap() : null; } }
2. objenesis.newInstance
- 如果是新的记录,那么会向map中添加该键值对,并返回null
- 如果已经存在,那么不会覆盖已有的值,直接返回已经存在的值
public <T> T newInstance(Class<T> clazz) { return this.getInstantiatorOf(clazz).newInstance(); } public <T> ObjectInstantiator<T> getInstantiatorOf(Class<T> clazz) { if (clazz.isPrimitive()) { throw new IllegalArgumentException("Primitive types can't be instantiated in Java"); } else if (this.cache == null) { return this.strategy.newInstantiatorOf(clazz); } else { ObjectInstantiator<?> instantiator = (ObjectInstantiator)this.cache.get(clazz.getName()); if (instantiator == null) { ObjectInstantiator<?> newInstantiator = this.strategy.newInstantiatorOf(clazz); instantiator = (ObjectInstantiator)this.cache.putIfAbsent(clazz.getName(), newInstantiator); if (instantiator == null) { instantiator = newInstantiator; } } return instantiator; } }
3. this.strategy.newInstantiatorOf
当前JVM平台是Java HotSpot,进入else分支,创建SunReflectionFactoryInstantiator实例对象
else { return new SunReflectionFactoryInstantiator(type); }
重点看下SunReflectionFactoryInstantiator的构造过程
public SunReflectionFactoryInstantiator(Class<T> type) { Constructor<Object> javaLangObjectConstructor = getJavaLangObjectConstructor(); this.mungedConstructor = SunReflectionFactoryHelper.newConstructorForSerialization(type, javaLangObjectConstructor); this.mungedConstructor.setAccessible(true); }
3.1 getJavaLangObjectConstructor返回Object类的构造器
private static Constructor<Object> getJavaLangObjectConstructor() { try { return Object.class.getConstructor((Class[])null); } catch (NoSuchMethodException var1) { throw new ObjenesisException(var1); } }
3.2 newConstructorForSerialization创建新的构造器mungedConstructor
- getReflectionFactoryClass通过Class.forName("sun.reflect.ReflectionFactory")获取ReflectionFactory Class
- createReflectionFactory调用ReflectionFactory类的getReflectionFactory方法获取reflectionFactory实例
- getNewConstructorForSerializationMethod获取ReflectionFactory类的newConstructorForSerialization Method
- 执行getNewConstructorForSerializationMethod方法,传入reflectionFactory,Test.class和Object构造器。
public static <T> Constructor<T> newConstructorForSerialization(Class<T> type, Constructor<?> constructor) { Class<?> reflectionFactoryClass = getReflectionFactoryClass(); Object reflectionFactory = createReflectionFactory(reflectionFactoryClass); Method newConstructorForSerializationMethod = getNewConstructorForSerializationMethod(reflectionFactoryClass); try { return (Constructor)newConstructorForSerializationMethod.invoke(reflectionFactory, type, constructor); } catch (IllegalArgumentException var6) { throw new ObjenesisException(var6); } catch (IllegalAccessException var7) { throw new ObjenesisException(var7); } catch (InvocationTargetException var8) { throw new ObjenesisException(var8); } }
- 调用ReflectionFactory.newConstructorForSerialization,由于var1 != var2,因此生成新的构造器
public Constructor<?> newConstructorForSerialization(Class<?> var1, Constructor<?> var2) { return var2.getDeclaringClass() == var1 ? var2 : this.generateConstructor(var1, var2); }该方法利用了asm字节码技术,将Test.class传入后返回 GeneratedSerializationConstructorAccessor1 对象,封装生成的新Constructor对象。
private final Constructor<?> generateConstructor(Class<?> var1, Constructor<?> var2) { SerializationConstructorAccessorImpl var3 = (new MethodAccessorGenerator()).generateSerializationConstructor(var1, var2.getParameterTypes(), var2.getExceptionTypes(), var2.getModifiers(), var2.getDeclaringClass()); Constructor var4 = this.newConstructor(var2.getDeclaringClass(), var2.getParameterTypes(), var2.getExceptionTypes(), var2.getModifiers(), langReflectAccess().getConstructorSlot(var2), langReflectAccess().getConstructorSignature(var2), langReflectAccess().getConstructorAnnotations(var2), langReflectAccess().getConstructorParameterAnnotations(var2)); this.setConstructorAccessor(var4, var3); var4.setAccessible(true); return var4; }
3.3 设置mungedConstructor的access为true,SunReflectionFactoryInstantiator构造完成
4. this.getInstantiatorOf(clazz).newInstance
getInstantiatorOf完成之后,进入SunReflectionFactoryInstantiator.newInstance实例化对象过程。
public T newInstance() { try { return this.mungedConstructor.newInstance((Object[])null); } catch (Exception var2) { throw new ObjenesisException(var2); } }
继续跟进Constructor类的newInstance方法。 最终调用ca.newInstance,ca也就是GeneratedSerializationConstructorAccessor1对象,实例化了Test对象。
public T newInstance(Object ... initargs) throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { if (!override) { if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) { Class<?> caller = Reflection.getCallerClass(); checkAccess(caller, clazz, null, modifiers); } } if ((clazz.getModifiers() & Modifier.ENUM) != 0) throw new IllegalArgumentException("Cannot reflectively create enum objects"); ConstructorAccessor ca = constructorAccessor; // read volatile if (ca == null) { ca = acquireConstructorAccessor(); } @SuppressWarnings("unchecked") T inst = (T) ca.newInstance(initargs); return inst; }
总结
综上步骤,完成一个对象的创建步骤如下
//创建Object构造器 Constructor<Object> objectConstructor = Object.class.getConstructor(null); //获取ReflectionFactory类 Class<?> reflectionFactoryClass = Class.forName("sun.reflect.ReflectionFactory"); //实例化ReflectionFactory对象 Object reflectionFactory = reflectionFactoryClass.getDeclaredMethod("getReflectionFactory").invoke(null); //调用newConstructorForSerialization,传入object构造器和Test类,创建新的构造器 Constructor<?> constructor = (Constructor<?>) reflectionFactoryClass .getDeclaredMethod("newConstructorForSerialization", Class.class, Constructor.class) .invoke(reflectionFactory, Test.class, objectConstructor); //设置access为true constructor.setAccessible(true); //实例化Test对象 Test test = (Test) constructor.newInstance(null); //调用方法 test.show();
最后
以上就是健康含羞草为你收集整理的Objenesis,另一种实例化对象的方式的全部内容,希望文章能够帮你解决Objenesis,另一种实例化对象的方式所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复