目录

概述

代码举例

源码剖析

模拟构造器反射生成对象实例


概述

        BeanDefinition 是用来描述 Bean 的,里面存放着关于 Bean 的一系列信息,比如 Bean 的作用域,Bean 所对应的 class, 是否懒加载,是否 Primary 等等。有了它 Spring 容器就掌握了实例化 bean 所需要的一些重要信息,Spring 才可以对其进行实例化。

        这里你可能会想,Spring 实例化一个对象怎么这么复杂,我们自己实例化的时候,不就拿到对应的类,new 一下不就完事了么,哪里需要什么 beanDefinition, 而 Spring 容器的作用不就是替我们保存一些实例,我们需要的时候向他索取,那么它也 new 一堆对象保存着不就行了么。

        其实问题也就出在 new 一堆对象这件事上,Spring容器管理着很多很多对象,比如你写一个@Component 注解,它就要实例化一个对象保存着,那么当你启动 Spring 容器的时候面对那么多要实例化的对象,它要先去实例化谁呢?比如说,你可能用了 @DepentOn 注解,就意味着一个 bean 是要优先于另外一个 bean 被实例化出来的。如果你用了@Lazy 注解,那么 Spring 容器启动的时候并不会实例化这个bean,而是等你真正问 Spring 容器要这个实例的时候,它才会给你创建一个 bean 出来。此外有的 bean是多例,而有的是单例,这样的话是不是发现只用一个类来 new 一个对象是不是根本满足不了上面的需求了。所以就有了 beanDefinition 的概念。它描述了 bean 的各种信息。使得 spring 容器能够很好的实例化管理 bean。

代码举例

        实体类代码

public class User {
    private String name;
    private String sex;

    public User() {

    }

    public User(String name, String sex) {
        this.name = name;
        this.sex = sex;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    @Override
    public String toString() {
        return "User{" +
            "name='" + name + '\'' +
            ", sex='" + sex + '\'' +
            '}';
    }
}

        测试代码:

public class TestDefinitionMain {
    public static void main(String[] args) {
        //实例化一个容器
        DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
        //实例化一个 beanDefinition
        RootBeanDefinition beanDefinition = new RootBeanDefinition(User.class);
        //注册 beanDefinition
        beanFactory.registerBeanDefinition("user1", beanDefinition);
        //从容器里获取 bean 实例,如果没有的话,会去创建一个 bean 并返回
        User user1 = beanFactory.getBean("user1", User.class);
        System.out.println(user1);

        //也可以通过操作 beanDefinition, 传入构造方法的参数,进而影响实例化 bean
        //实例化一个 beanDefinition
        RootBeanDefinition beanDefinition2 = new RootBeanDefinition(User.class);
        //添加构造方法的参数
        ConstructorArgumentValues constructorArgumentValues = new ConstructorArgumentValues();
        constructorArgumentValues.addIndexedArgumentValue(0, "cison");
        constructorArgumentValues.addIndexedArgumentValue(1, "男");
        beanDefinition2.setConstructorArgumentValues(constructorArgumentValues);
        //注册bean定义
        beanFactory.registerBeanDefinition("user2", beanDefinition2);
        User user2 = beanFactory.getBean("user2", User.class);
        System.out.println(user2);
    }
}

 运行结果如下,至此我们已经通过注册 bean 定义,进而在容器中实例化一个 bean:

User{name='null', sex='null'}
User{name='cison', sex='男'}

源码剖析

        从上面实例代码可以看到,主要的两个方法为 beanFactory.registerBeanDefinition() 和beanFactory.getBean(),分别剖析一下这两个方法到底做了什么。

  • 点进去 beanFactory.registerBeanDefinition() ,源码如下:
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
			throws BeanDefinitionStoreException {

		Assert.hasText(beanName, "Bean name must not be empty");
		Assert.notNull(beanDefinition, "BeanDefinition must not be null");
        //我们所用的是 RootBeanDefinition, 所以 if 条件这里不用考虑
		if (beanDefinition instanceof AbstractBeanDefinition) {
			try {
				((AbstractBeanDefinition) beanDefinition).validate();
			}
			catch (BeanDefinitionValidationException ex) {
				throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
						"Validation of bean definition failed", ex);
			}
		}
        
        //判断是否已经注册了该 bean 的 bean定义,很明显我们第一次注册,这里获取为空,故这个 if 条件也跳过
		BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);
		if (existingDefinition != null) {
			if (!isAllowBeanDefinitionOverriding()) {
				throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition);
			}
			else if (existingDefinition.getRole() < beanDefinition.getRole()) {
				// e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE
				if (logger.isInfoEnabled()) {
					logger.info("Overriding user-defined bean definition for bean '" + beanName +
							"' with a framework-generated bean definition: replacing [" +
							existingDefinition + "] with [" + beanDefinition + "]");
				}
			}
			else if (!beanDefinition.equals(existingDefinition)) {
				if (logger.isDebugEnabled()) {
					logger.debug("Overriding bean definition for bean '" + beanName +
							"' with a different definition: replacing [" + existingDefinition +
							"] with [" + beanDefinition + "]");
				}
			}
			else {
				if (logger.isTraceEnabled()) {
					logger.trace("Overriding bean definition for bean '" + beanName +
							"' with an equivalent definition: replacing [" + existingDefinition +
							"] with [" + beanDefinition + "]");
				}
			}
			this.beanDefinitionMap.put(beanName, beanDefinition);
		}
		else {
            //这里判断bean是否已经开始创建,很明显这里第一次注册bean定义,是没有的进行创建的
			if (hasBeanCreationStarted()) {
				// Cannot modify startup-time collection elements anymore (for stable iteration)
				synchronized (this.beanDefinitionMap) {
					this.beanDefinitionMap.put(beanName, beanDefinition);
					List<String> updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1);
					updatedDefinitions.addAll(this.beanDefinitionNames);
					updatedDefinitions.add(beanName);
					this.beanDefinitionNames = updatedDefinitions;
					removeManualSingletonName(beanName);
				}
			}
			else {
                //最终逻辑会走到这里
				// Still in startup registration phase
				this.beanDefinitionMap.put(beanName, beanDefinition);
				this.beanDefinitionNames.add(beanName);
				removeManualSingletonName(beanName);
			}
			this.frozenBeanDefinitionNames = null;
		}

		if (existingDefinition != null || containsSingleton(beanName)) {
			resetBeanDefinition(beanName);
		}
		else if (isConfigurationFrozen()) {
			clearByTypeCache();
		}
	}

        从上面可以看到,代码最终会走到如下代码段,由此可知,注册bean定义,其实就是在将bean定义的信息,保存到 bean 容器的两个局部变量里,其中 beanDefinitionMap 保存bean名称和bean定义的映射关系,beanDefinitionNames 保存所有bean的名称。

this.beanDefinitionMap.put(beanName, beanDefinition);
this.beanDefinitionNames.add(beanName);
  • beanFactory.getBean()

        这是创建 bean 的方法,点进去可以看到如下代码

public <T> T getBean(String name, Class<T> requiredType) throws BeansException {
    return doGetBean(name, requiredType, null, false);
}

        可以看到真正创建 bean 的方法为 doGetBean(),继续往下走

    protected <T> T doGetBean(
        String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
        throws BeansException {

        //该方法判断该 bean 是否有别名,如果有的话就转换一下名称
        String beanName = transformedBeanName(name);
        Object bean;

        // Eagerly check singleton cache for manually registered singletons.
        //该方法从三级缓存里尝试获取 bean,因为当前是第一次创建,故返回值为 null, 故下面 if 逻辑不会进去
        Object sharedInstance = getSingleton(beanName);
        if (sharedInstance != null && args == null) {
            if (logger.isTraceEnabled()) {
                // 与下面的 prototype 的 bean 不同,如果创建单例 bean 的时候发现该 bean 正在被创建,这说明出现了循环依赖,但是并没有立刻抛出异常,而是会将当前还没有完全创建好的 bean 返回(当然这也可能会出现问题,后面文章再分析)
                if (isSingletonCurrentlyInCreation(beanName)) {
                    logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +
                        "' that is not fully initialized yet - a consequence of a circular reference");
                }
                else {
                    logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
                }
            }
            bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
        }

        else {
            // Fail if we're already creating this bean instance:
            // We're assumably within a circular reference.
            // Spring 只解决了单例 bean 的循环依赖问题,如果是 prototype 类型的 bean 出现了循环依赖则会跑出异常
            if (isPrototypeCurrentlyInCreation(beanName)) {
                throw new BeanCurrentlyInCreationException(beanName);
            }

            // Check if bean definition exists in this factory.
            // 如果当前容器没有获取到bean定义,则会尝试从父容器中获取
            BeanFactory parentBeanFactory = getParentBeanFactory();
            if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
                // Not found -> check parent.
                String nameToLookup = originalBeanName(name);
                if (parentBeanFactory instanceof AbstractBeanFactory) {
                    return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
                        nameToLookup, requiredType, args, typeCheckOnly);
                }
                else if (args != null) {
                    // Delegation to parent with explicit args.
                    return (T) parentBeanFactory.getBean(nameToLookup, args);
                }
                else if (requiredType != null) {
                    // No args -> delegate to standard getBean method.
                    return parentBeanFactory.getBean(nameToLookup, requiredType);
                }
                else {
                    return (T) parentBeanFactory.getBean(nameToLookup);
                }
            }

            if (!typeCheckOnly) {
                markBeanAsCreated(beanName);
            }

            try {
                // 如果当前容器和父容器中都有改bean定义,就会将二者合并一下
                RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
                checkMergedBeanDefinition(mbd, beanName, args);

                // Guarantee initialization of beans that the current bean depends on.
                // 如果配置了 @Dependon, 那么就会创建它所依赖的 bean
                String[] dependsOn = mbd.getDependsOn();
                if (dependsOn != null) {
                    for (String dep : dependsOn) {
                        // 如果互相dependson, 就会抛出异常,注意这里不是循环依赖,而是二者都标注了 @DependOn 对方的注解,都想让对方先创建出来
                        if (isDependent(beanName, dep)) {
                            throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                                "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
                        }
                        registerDependentBean(dep, beanName);
                        try {
                            // 创建当前 bean 依赖的 bean, 也是调用 getBean 方法
                            getBean(dep);
                        }
                        catch (NoSuchBeanDefinitionException ex) {
                            throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                                "'" + beanName + "' depends on missing bean '" + dep + "'", ex);
                        }
                    }
                }

                // Create bean instance.
                if (mbd.isSingleton()) {
                    // 创建单例 bean, 其中 getSingleton 方法是创建 bean 之前进行一写预备工作,createBean 是一个回调方法,该方法是真正实例化 bean 的地方
                    sharedInstance = getSingleton(beanName, () -> {
                        try {
                            return createBean(beanName, mbd, args);
                        }
                        catch (BeansException ex) {
                           //.. 省略部分处理异常代码
                        }
                    });
                    bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
                }

        // ....省略部分代码
        return (T) bean;
    }

        通过以上代码及注释,我们会走到如下代码这一行,这里是获取 bean 定义的,那么怎么获取呢,由上面注册bean定义的流程可以猜测,因为注册bean定义的时候,其实是把 bean 定义放入到了容器的一个局部变量 beanDefinitionMap 里,那么当要获取 bean 定义的时候,最终应该也是是从beanDefinitionMap 中来根据名称获取bean定义的。下面我们就继续跟进下面这行代码,来验证我们的猜想。

RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);

        点进去 getMergedLocalBeanDefinition 可以看到

protected RootBeanDefinition getMergedLocalBeanDefinition(String beanName) throws BeansException {
    // Quick check on the concurrent map first, with minimal locking.
    //这一行是获取合并之后的 bean 定义的,因为我们目前没有涉及与父 bean 的合并,故获取到 null
	RootBeanDefinition mbd = this.mergedBeanDefinitions.get(beanName);
	if (mbd != null && !mbd.stale) {
		return mbd;
	}
    //最终会走到这一行
	return getMergedBeanDefinition(beanName, getBeanDefinition(beanName));
}

        我们留意到最后一行调用方法的第二个参数,是调用另外一个方法的返回值,我们跟进getBeanDefinition(beanName)

public BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException {
    //果然是你!!!
	BeanDefinition bd = this.beanDefinitionMap.get(beanName);
	if (bd == null) {
		if (logger.isTraceEnabled()) {
			logger.trace("No bean named '" + beanName + "' found in " + this);
		}
		throw new NoSuchBeanDefinitionException(beanName);
	}
	return bd;
}

        我们可以看到,最终果然是从 beanDefinitionMap 中获取到的 bean 定义。至于getMergedBeanDefinition 方法,它是用来合并父亲和孩子之间的bean定义的,目前我们不需要,故暂不讨论。接着我们返回创建 bean 的主流程中去。

RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);

        这里就得到了 bean 定义,然后接下来的核心代码如下

//首先从bean定义中获取 dependOn 信息, 在声明bean的时候可以使用 @Dependon 注解指定在哪些bean创建之后再创建当前bean,我们样例中没有配置,故这里获取到 null,
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
    for (String dep : dependsOn) {
	    if (isDependent(beanName, dep)) {
			throw new BeanCreationException(mbd.getResourceDescription(), beanName,"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
		}
		registerDependentBean(dep, beanName);
		try {
			getBean(dep);
		}
		catch (NoSuchBeanDefinitionException ex) {
		    throw new BeanCreationException(mbd.getResourceDescription(), beanName,
				"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
		}
	}
}
// Create bean instance.
if (mbd.isSingleton()) {
    //单例bean的创建流程
    sharedInstance = getSingleton(beanName, () -> {
	    try {
			return createBean(beanName, mbd, args);
		}
		catch (BeansException ex) {
            destroySingleton(beanName);
			throw ex;
						}
	    });
	bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}

        由上也可以看到 beanDefinition 的作用,可以看到它存储了 bean 的 dependOn 信息和作用域信息,用于控制创建 bean 的流程, 接下来就是真正创建 bean 的流程了,getSingleton 传入bean名称和一个钩子函数,在 getSingleton 方法里有这个一行代码 singletonObject = singletonFactory.getObject(); 这就是调用钩子函数来创建bean实例,所以我们这里直接跟进钩子函数的 createBean(beanName, mbd, args) 方法

protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
			throws BeanCreationException {

		if (logger.isTraceEnabled()) {
			logger.trace("Creating instance of bean '" + beanName + "'");
		}
		RootBeanDefinition mbdToUse = mbd;

		// Make sure bean class is actually resolved at this point, and
		// clone the bean definition in case of a dynamically resolved Class
		// which cannot be stored in the shared merged bean definition.
		Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
		if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
			mbdToUse = new RootBeanDefinition(mbd);
			mbdToUse.setBeanClass(resolvedClass);
		}

		// Prepare method overrides.
		try {
			mbdToUse.prepareMethodOverrides();
		}
		catch (BeanDefinitionValidationException ex) {
			throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
					beanName, "Validation of method overrides failed", ex);
		}

		try {
			// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
            //这里是常识创建代理对象,因为我们样例没有配置代理,故这里获取到 null
			Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
			if (bean != null) {
				return bean;
			}
		}
		catch (Throwable ex) {
			throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
					"BeanPostProcessor before instantiation of bean failed", ex);
		}

		try {
            //创建普通 bean 的方法
			Object beanInstance = doCreateBean(beanName, mbdToUse, args);
			if (logger.isTraceEnabled()) {
				logger.trace("Finished creating instance of bean '" + beanName + "'");
			}
			return beanInstance;
		}
		catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
			// A previously detected exception with proper bean creation context already,
			// or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.
			throw ex;
		}
		catch (Throwable ex) {
			throw new BeanCreationException(
					mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
		}
	}

        上面这段代码有两段逻辑,先尝试创建代理对象,如果该 bean 需要被代理,那么就会创建代理对象成功并返回,否则就会进入下面创建普通 bean 的流程 doCreateBean(beanName, mbdToUse, args)

protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
			throws BeanCreationException {

		// Instantiate the bean.
		BeanWrapper instanceWrapper = null;
		if (mbd.isSingleton()) {
			instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
		}
		if (instanceWrapper == null) {
            //在这里通过构造器反射获取到对象实例
			instanceWrapper = createBeanInstance(beanName, mbd, args);
		}
		Object bean = instanceWrapper.getWrappedInstance();
		Class<?> beanType = instanceWrapper.getWrappedClass();
		if (beanType != NullBean.class) {
			mbd.resolvedTargetType = beanType;
		}

		// Allow post-processors to modify the merged bean definition.
		synchronized (mbd.postProcessingLock) {
			if (!mbd.postProcessed) {
				try {
					applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
				}
				catch (Throwable ex) {
					throw new BeanCreationException(mbd.getResourceDescription(), beanName,
							"Post-processing of merged bean definition failed", ex);
				}
				mbd.postProcessed = true;
			}
		}

		// Eagerly cache singletons to be able to resolve circular references
		// even when triggered by lifecycle interfaces like BeanFactoryAware.
		boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
				isSingletonCurrentlyInCreation(beanName));
		if (earlySingletonExposure) {
			if (logger.isTraceEnabled()) {
				logger.trace("Eagerly caching bean '" + beanName +
						"' to allow for resolving potential circular references");
			}
			addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
		}

		// Initialize the bean instance.
		Object exposedObject = bean;
		try {
			populateBean(beanName, mbd, instanceWrapper);
			exposedObject = initializeBean(beanName, exposedObject, mbd);
		}
		catch (Throwable ex) {
			if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
				throw (BeanCreationException) ex;
			}
			else {
				throw new BeanCreationException(
						mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
			}
		}

		if (earlySingletonExposure) {
			Object earlySingletonReference = getSingleton(beanName, false);
			if (earlySingletonReference != null) {
				if (exposedObject == bean) {
					exposedObject = earlySingletonReference;
				}
				else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
					String[] dependentBeans = getDependentBeans(beanName);
					Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
					for (String dependentBean : dependentBeans) {
						if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
							actualDependentBeans.add(dependentBean);
						}
					}
					if (!actualDependentBeans.isEmpty()) {
						throw new BeanCurrentlyInCreationException(beanName,
								"Bean with name '" + beanName + "' has been injected into other beans [" +
								StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
								"] in its raw version as part of a circular reference, but has eventually been " +
								"wrapped. This means that said other beans do not use the final version of the " +
								"bean. This is often the result of over-eager type matching - consider using " +
								"'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.");
					}
				}
			}
		}

		// Register bean as disposable.
		try {
			registerDisposableBeanIfNecessary(beanName, bean, mbd);
		}
		catch (BeanDefinitionValidationException ex) {
			throw new BeanCreationException(
					mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
		}

		return exposedObject;
	}

               该方法里获得实例对象是这一行代码,它底层比较复杂,但是原理就是获取实例类的构造器,通过反射生成一个对象。至此,我们通过getBean()方法就得到了一个实例 bean,后续会有一些初始化,实例化,增强的逻辑,这里暂时就不展开了。

instanceWrapper = createBeanInstance(beanName, mbd, args);

模拟构造器反射生成对象实例

public class TestDefinitionMain {
    public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        //实例化一个容器
        DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
        //实例化一个 beanDefinition
        RootBeanDefinition beanDefinition = new RootBeanDefinition(User.class);
        //注册 beanDefinition
        beanFactory.registerBeanDefinition("user1", beanDefinition);
        //从容器里获取 bean 实例,如果没有的话,会去创建一个 bean 并返回
        User user1 = beanFactory.getBean("user1", User.class);
        System.out.println(user1);

        //也可以通过操作 beanDefinition, 传入构造方法的参数,进而影响实例化 bean
        //实例化一个 beanDefinition
        RootBeanDefinition beanDefinition2 = new RootBeanDefinition(User.class);
        //添加构造方法的参数
        ConstructorArgumentValues constructorArgumentValues = new ConstructorArgumentValues();
        constructorArgumentValues.addIndexedArgumentValue(0, "cison");
        constructorArgumentValues.addIndexedArgumentValue(1, "男");
        beanDefinition2.setConstructorArgumentValues(constructorArgumentValues);
        //注册bean定义
        beanFactory.registerBeanDefinition("user2", beanDefinition2);
        User user2 = beanFactory.getBean("user2", User.class);
        System.out.println(user2);

        //构造器反射获取实例 candidate.newInstance();
        Constructor<?>[] candidates = User.class.getDeclaredConstructors();
        for (Constructor candidate : candidates) {
            int parameterCount = candidate.getParameterCount();
            if (parameterCount == 0) {
                //通过反射实例化对象
                User user3 = (User) candidate.newInstance();
                System.out.println("user3:" + user3);
            } else {
                //模拟解析参数
                ConstructorArgumentValues paramValues = beanDefinition2.getConstructorArgumentValues();
                Map<Integer, ConstructorArgumentValues.ValueHolder> indexedArgumentValues = paramValues.getIndexedArgumentValues();
                Object[] args0 = new Object[2];
                args0[0] = indexedArgumentValues.get(0).getValue();
                args0[1] = indexedArgumentValues.get(1).getValue();
                //通过反射实例化对象
                User user4 = (User) candidate.newInstance(args0);
                System.out.println("user4:" + user4);
            }
        }
    }
}

       执行结果: 

User{name='null', sex='null'}
User{name='cison', sex='男'}
user3:User{name='null', sex='null'}
user4:User{name='cison', sex='男'}

        

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐