package org.hy.common;

import java.io.Serializable;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.math.BigDecimal;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.hy.common.comparate.MethodComparator;
import org.hy.common.comparate.MethodFieldComparator;





/**
 * 方法的反射。
 * 
 * 1. 可实现xxx.yyy.www(或getXxx.getYyy.setWww)全路径的解释。不再区分大小写
 * 2. 可实现xxx.yyy.www(或getXxx.getYyy.getWww)全路径的解释。不再区分大小写
 * 3. 可实现xxx(p1).yyy(p1 ,p2).www 方法带参数的全路径的解释。不再区分大小写
 * 4. 无须反射,只许简单的执行方法就成。应用于:外界已明确了待执行的方法(通常是getter方法)。
 * 
 * @author      ZhengWei(HY)
 * @createDate  2012-09-21
 * @version     v2.0  2014-07-11  可实现xxx(p1).yyy(p1 ,p2).www 方法带参数的全路径的解释。
 *              v3.0  2016-03-18  添加新的构造器。无须反射,只许简单的执行方法就成。应用于:外界已明确了待执行的方法(通常是getter方法)。
 *                                添加:向数据库表插入数据时,通过Java生成主键的功能。与SQL占位符配合使用。
 *              v4.0  2016-07-30  添加:getMapValue()方法,从Map集合中取值。实现xxx.yyy.www(或getXxx.getYyy.getWww)全路径的解释
 *              v4.1  2017-01-21  修正:isExtendImplement()方法对接口继承的接口与要作判定。
 *              v4.2  2017-02-15  添加:将"GET"、"SET"两个分区关键字对外公开。
 *              v5.0  2017-03-18  添加:Class<?> 类型对识别方法反射的构造器
 *              v5.1  2017-03-23  添加:xxx.$getYyy.www 全路径中$符号后跟的为完整方法名称的解释功能。
 *                                     即,全路径中一部是简写方法名称的方式,一部又是方法的完整名称。
 *              v6.0  2017-06-15  添加:MethodReflect()构造器中入参 "i_MethodURL方法全路径" 中的每个方法名称,不再区分大小写
 *              v7.0  2017-06-23  修正:三个invokeForInstance(...)方法在中间实现对象为Null的处理。
 *              v8.0  2017-07-12  修改:所有方法名称的判定都不再区分大小。
 *                                修正:当方法名称正的以$开头时($为本类的关键字符,见v5.1),也要能正确匹配到方法。parser()方法除外。
 *              v9.0  2017-11-24  添加:invokeSet(...)调用对象的Setter赋值。
 *              v10.0 2017-12-18  添加:getParameterAnnotations(...)
 *              v11.0 2017-12-23  修正:MethodReflect实现序列接口,但this.methods的类型Method是非序列,用MethodInfo代替。
 *              v12.0 2018-01-18  添加:支持BigDecimal类型
 *              v12.1 2018-01-29  添加:扫描项目所有类时,当发现某一类引用的类不存在时,只错误提示不中断服务。
 *              v12.2 2018-03-11  添加:解释方法全路径parser(),最后一个Getter方法支持isXXX()方法,支持逻辑方法。
 *              v12.3 2018-04-26  添加:按方法对应的成员属性名称在类中的编程编写的顺序排序的getGetSetMethods(...)。
 *              v12.4 2018-05-04  添加:isExtendImplement()方法判定基本类型与包装类型是否一样。
 *              v12.5 2018-05-08  添加:支持枚举toString()的匹配
 *                                修改: 当子类实现父类接口时,方法重载时,可能出现方法名称相同的两个getter方法。
 *                                      方法按修饰符排序后取首个方法,不再向外界抛错。
 *              v12.6 2018-05-15  添加:数据库java.sql.Timestamp时间的转换
 *              v13.0 2020-01-14  添加:获取排除某些前缀的成员方法 getMethodsExcludeStart()
 */
public class MethodReflect implements Serializable
{
    
    private static final long serialVersionUID = -4388208505011166797L;
    
    

    /** Getter、is方法的分区关键字。主用于 getGetSetMethods() 方法的返回值:分区结构 */
    public static final String $Partition_GET         = "GET";
    
    /** Setter方法的分区关键字。主用于 getGetSetMethods() 方法的返回值:分区结构 */
    public static final String $Partition_SET         = "SET";
    
    
    
    /**
     * 类似于Excel单元格中的固定引用单元格的标示符。
     * 
     * 当方法的全路径为:xxx.$getYyy.www 时,$符号表示 getYyy 是一个方法的完整名称,无须再添加 "get"、"is" 或 "set" 前缀。
     * 
     * 只对 isNorm = true 有效
     */
    public final static String $FixedMethodName = "$";
    
    /**
     * 正则表达式对:方法名称的识别
     * 如:add(row)
     */
    private final static String $REGEX_METHOD         = "[\\" + $FixedMethodName + "\\w]+[\\(]";
    
    /**
     * 正则表达式对:方法填写有效性的验证。
     * 如:xxx(p1 ,p2 ,... pn)
     * 如:xxx(o1.p1 ,o2.p1 ,... on.pn)
     */
    private final static String $REGEX_METHOD_VERIFY  = "^[\\" + $FixedMethodName + "\\w]+\\( *((\\w+\\.\\w+ *, *)|(\\w+ *, *))*((\\w+\\.\\w+)|(\\w+)) *\\)$";
    
    
    
	/** Setter规范的方法 */
	public final static int $NormType_Setter = 1;
	
	/** Getter规范的方法 */
	public final static int $NormType_Getter = -1;
	
	
	
	/** 
	 * i_MethodURL整体是否为规范的setter或getter方法
	 * 
	 * 即,当 isNorm = true  时,i_MethodURL = xxx.yyy.www 
	 * 相等于 isNorm = false 时,i_MethodURL = getXxx.getYyy.setWww
	 **/
	private boolean                isNorm;
	
	/** 
	 *  规范的类型
	 *  
	 *  1. normType =  1 为 setter 方法,如:getXxx.getYyy.setWww
	 *  2. normType = -1 为 getter 方法,如:getXxx.getYyy.getWww
	 **/
	private int                    normType;
	
	/** 方法全路径的Mehod返回对象类型的集合 */
    private List<Class<?>>         classes;
	
	/** 方法全路径的Mehod返回对象实例的集合。第一元素为构造器的第一个参数值 */
	private List<Object>           instances;
	
	/** 
	 * 方法全路径的Mehod的集合 
	 * 外层List对应:方法全路径上.第几层次上方法
	 * 内层List对应:具体层次上的多个相同重载的方法
	 */
	private List<List<MethodInfo>> methods;
	
	/**
	 * 方法全路径的Mehod的集合的参数集合
	 * 外层List对应:方法全路径上.第几层次上方法
	 * 内层List对应:具体层次上的方法的多个入参参数
	 */
	private List<List<String>>     methodsParams;
	
	/** 方法全路径的分段数组 */
	private String []              methodNames;
	
	/** 方法名称的全路径 */
	private String                 methodURL;
	
	
	
	/**
     * 方法填写有效性的验证
     * 
     * 如:xxx(p1 ,p2 ,... pn)
     * 如:xxx(o1.p1 ,o2.p1 ,... on.pn)
     * 
     * @param i_Text
     * @return
     */
    public static boolean methodVerify(String i_Text)
    {
        if ( Help.isNull(i_Text) )
        {
            return false;
        }
        
        Pattern v_Pattern = Pattern.compile($REGEX_METHOD_VERIFY);
        Matcher v_Matcher = v_Pattern.matcher(i_Text);
        
        return v_Matcher.find();
    }
    
    
    
    /**
     * 解释如 xxx(p1 ,p2 ,... pn) 格式的方法名称
     * 
     * @param i_Text
     * @return
     */
    public static String parserMethodName(String i_Text)
    {
        if ( methodVerify(i_Text) )
        {
            Pattern v_Pattern    = Pattern.compile($REGEX_METHOD);
            Matcher v_Matcher    = v_Pattern.matcher(i_Text);
            String  v_MethodName = "";
            
            // 识别行级填充方法名称
            if ( v_Matcher.find() )
            {
                v_MethodName = v_Matcher.group();
                v_MethodName = v_MethodName.substring(0 ,v_MethodName.length() - 1);
            }
            else
            {
                throw new NoSuchMethodError("Method name[" + i_Text + "] is not exist.");
            }
            
            return v_MethodName;
        }
        else
        {
            return null;
        }
    }
    
    
    
    /**
     * 解释如 xxx(p1 ,p2 ,... pn) 格式的方法参数
     * 
     * @param i_Text
     * @return
     */
    public static String [] parserMethodParams(String i_Text)
    {
        if ( methodVerify(i_Text) )
        {
            Pattern v_Pattern    = Pattern.compile($REGEX_METHOD);
            Matcher v_Matcher    = v_Pattern.matcher(i_Text);
            String  v_MethodName = "";
            int     v_EndIndex   = 0;
            String  v_Params     = null;
            
            
            // 识别行级填充方法名称
            if ( v_Matcher.find() )
            {
                v_MethodName = v_Matcher.group();
                v_MethodName = v_MethodName.substring(0 ,v_MethodName.length() - 1);
                v_EndIndex   = v_Matcher.end();
            }
            else
            {
                throw new NoSuchMethodError("Method name[" + i_Text + "] is not exist.");
            }
            
            
            v_Params = i_Text.substring(v_EndIndex ,i_Text.length() - 1);
            return v_Params.split(",");
        }
        else
        {
            return new String[0];
        }
    }
    
	
    
    /**
     * 继承及实现的判断
     * 
     * 1. 判断某个类是否实现了i_InterfaceClass接口
     * 2. 递归判断某个类实现的接口中是否继承了i_InterfaceClass接口
     * 3. 递归判断某个类实现的接口的继承的接口是否继承了i_InterfaceClass接口
     * 4. 判断某个类是否继承了i_InterfaceClass类
     * 5. 递归判断某个类的父类是否实现了i_InterfaceClass接口
     * 6. 递归判断某个类的父类是否继承了i_InterfaceClass类
     * 
     * @param i_ObjectClass     类的元类型
     * @param i_InterfaceClass  接口的元类型
     * @return
     */
    public static boolean isExtendImplement(Object i_Object ,Class<?> i_InterfaceClass)
    {
        return isExtendImplement(i_Object.getClass() ,i_InterfaceClass);
    }
    
    
    
    /**
     * 继承及实现的判断
     * 
     * 1. 判断某个类是否实现了i_InterfaceClass接口
     * 2. 递归判断某个类实现的接口中是否继承了i_InterfaceClass接口
     * 3. 递归判断某个类实现的接口的继承的接口是否继承了i_InterfaceClass接口
     * 4. 判断某个类是否继承了i_InterfaceClass类
     * 5. 递归判断某个类的父类是否实现了i_InterfaceClass接口
     * 6. 递归判断某个类的父类是否继承了i_InterfaceClass类
     * 
     * @param i_ObjectClass     类的元类型
     * @param i_InterfaceClass  接口的元类型
     * @return
     */
    public static boolean isExtendImplement(Class<?> i_ObjectClass ,Class<?> i_InterfaceClass)
    {
        if ( i_ObjectClass == i_InterfaceClass )
        {
            return true;
        }
        else if ( i_ObjectClass == null || i_InterfaceClass == null )
        {
            return false;
        }
        // 判定Boolean.class == boolean.class  ZhengWei(HY) Add 2018-05-04 
        // 对于Number类型,不处理
        else if ( i_ObjectClass.getName().startsWith("java.lang") ) 
        {
            String v_LangName1 = i_ObjectClass   .getSimpleName().toLowerCase();
            String v_LangName2 = i_InterfaceClass.getSimpleName().toLowerCase();
            
            if ( v_LangName1.startsWith(v_LangName2) )
            {
                return true;
            }
            else
            {
                // 不能简单的返回 false。如当 String 与 java.io.Serializable 比较时也应返回true的。
            }
        }
        // 判定boolean.class == Boolean.class  ZhengWei(HY) Add 2018-05-04
        // 对于Number类型,不处理
        else if ( i_InterfaceClass.getName().startsWith("java.lang") ) 
        {
            String v_LangName1 = i_InterfaceClass.getSimpleName().toLowerCase();
            String v_LangName2 = i_ObjectClass   .getSimpleName().toLowerCase();
            
            if ( v_LangName1.startsWith(v_LangName2) )
            {
                return true;
            }
            else
            {
                // 不能简单的返回 false。如当 String 与 java.io.Serializable 比较时也应返回true的。
            }
        }
        
        Class<?> [] v_Interfaces = i_ObjectClass.getInterfaces();
        
        for (int i=0; i<v_Interfaces.length; i++)
        {
            // 判断某个类是否实现了i_InterfaceClass接口
            if ( v_Interfaces[i] == i_InterfaceClass )
            {
                return true;
            }
            
            // 递归判断某个类实现的接口中是否继承了i_InterfaceClass接口
            if ( isExtendImplement(v_Interfaces[i].getSuperclass() ,i_InterfaceClass) )
            {
                return true;
            }
            
            // 判断接口类的继承的接口  ZhengWei(HY) Add 2017-01-21
            Class<?> [] v_Interface_Interfaces = v_Interfaces[i].getInterfaces();
            for (int x=0; x<v_Interface_Interfaces.length; x++)
            {
                if ( isExtendImplement(v_Interface_Interfaces[x] ,i_InterfaceClass) )
                {
                    return true;
                }
            }
        }
        
        // 判断某个类是否继承了i_InterfaceClass类
        if ( i_ObjectClass.getSuperclass() == i_InterfaceClass )
        {
            return true;
        }
        else if ( i_ObjectClass.getSuperclass() == Object.class )
        {
            return false;
        }
        else
        {
            // 递归判断某个类的父类是否实现了i_InterfaceClass接口
            // 递归判断某个类的父类是否继承了i_InterfaceClass类
            return isExtendImplement(i_ObjectClass.getSuperclass() ,i_InterfaceClass);
        }
    }
    
    
    
    /**
     * 获取某个Java类的属性上首个位置的范型Class原型
     * 
     * @param i_Class
     * @param i_FieldName  属性名称(只能是本类自有的属性)
     * @return
     */
    public static Class<?> getGenerics(Class<?> i_Class ,String i_FieldName)
    {
        try
        {
            return getGenerics(i_Class.getDeclaredField(i_FieldName));
        }
        catch (Exception exce)
        {
            return null;
        }
    }
    
    
    
    /**
     * 获取某个Java类的属性上首个位置的范型Class原型
     * 
     * @param i_Class
     * @param i_FieldName      属性名称(只能是本类自有的属性)
     * @param i_GenericsIndex  范型的位置
     * @return
     */
    public static Class<?> getGenerics(Class<?> i_Class ,String i_FieldName ,int i_GenericsIndex)
    {
        try
        {
            return getGenerics(i_Class.getDeclaredField(i_FieldName) ,i_GenericsIndex);
        }
        catch (Exception exce)
        {
            return null;
        }
    }
    
    
    
    /**
     * 获取某个Java类的方法上某个入参参数的某个位置的范型Class原型
     * 
     * @param i_Class
     * @param i_MethodName     方法名称
     * @param i_ParamSize      方法入参的个数
     * @param i_GenericsIndex  范型的位置
     * @return
     */
    public static Class<?> getGenerics(Class<?> i_Class ,String i_MethodName ,int i_ParamSize ,int i_GenericsIndex)
    {
        try
        {
            return getGenerics(getMethods(i_Class ,i_MethodName ,i_ParamSize).get(0) ,i_GenericsIndex);
        }
        catch (Exception exce)
        {
            return null;
        }
    }
    
    
    
    /**
     * 获取属性上首个位置的范型Class原型
     * 
     * @param i_Field
     * @return
     */
    public static Class<?> getGenerics(Field i_Field)
    {
        return getGenerics(i_Field ,0);
    }
    
    
    
    /**
     * 获取属性上某个位置的范型Class原型
     * 
     * @param i_Field
     * @param i_GenericsIndex  范型的位置
     * @return
     */
    public static Class<?> getGenerics(Field i_Field ,int i_GenericsIndex)
    {
        try
        {
            ParameterizedType v_PType = (ParameterizedType) i_Field.getGenericType();
            Type              v_Type  = v_PType.getActualTypeArguments()[i_GenericsIndex];
            return (Class<?>)v_Type;
        }
        catch (Exception exce)
        {
            return null;
        }
    }
    
    
    
    /**
     * 获取方法首个入参参数上的首个位置的范型Class原型
     * 
     * @param i_Method
     * @return
     */
    public static Class<?> getGenerics(Method i_Method)
    {
        return getGenerics(i_Method ,0 ,0);
    }
    
    
    
    /**
     * 获取方法某个入参参数上的首个位置的范型Class原型
     * 
     * @param i_Method
     * @param i_ParamIndex
     * @return
     */
    public static Class<?> getGenerics(Method i_Method ,int i_ParamIndex)
    {
        return getGenerics(i_Method ,i_ParamIndex ,0);
    }
    
    
    
    /**
     * 获取方法某个入参参数上的某个位置的范型Class原型
     * 
     * @param i_Method
     * @param i_ParamIndex      方法的入参参数位置
     * @param i_GenericsIndex   入参参数范型的位置
     * @return
     */
    public static Class<?> getGenerics(Method i_Method ,int i_ParamIndex ,int i_GenericsIndex)
    {
        try
        {
            ParameterizedType v_PType = (ParameterizedType) i_Method.getGenericParameterTypes()[i_ParamIndex];
            Type              v_Type  = v_PType.getActualTypeArguments()[i_GenericsIndex];
            return (Class<?>)v_Type;
        }
        catch (Exception exce)
        {
            return null;
        }
    }
    
    
    
    /**
     * 获取方法返回值上的首个位置的范型Class原型
     * 
     * @param i_Class
     * @param i_MethodName      方法名称
     * @param i_ParamSize       方法入参的个数
     * @return
     */
    public static GenericsReturn getGenericsReturn(Class<?> i_Class ,String i_MethodName ,int i_ParamSize)
    {
        return getGenericsReturn(i_Class ,i_MethodName ,i_ParamSize ,0);
    }
    
    
    
    /**
     * 获取方法返回值上的某个位置的范型Class原型
     * 
     * @param i_Class
     * @param i_MethodName      方法名称
     * @param i_ParamSize       方法入参的个数
     * @param i_GenericsIndex   范型的位置
     * @return
     */
    public static GenericsReturn getGenericsReturn(Class<?> i_Class ,String i_MethodName ,int i_ParamSize ,int i_GenericsIndex)
    {
        try
        {
            return getGenericsReturn(getMethods(i_Class ,i_MethodName ,i_ParamSize).get(0) ,i_GenericsIndex);
        }
        catch (Exception exce)
        {
            return null;
        }
    }
    
    
    
    /**
     * 获取方法返回值上的首个位置的范型Class原型
     * 
     * @param i_Method
     * @return
     */
    public static GenericsReturn getGenericsReturn(Method i_Method)
    {
        return getGenericsReturn(i_Method ,0);
    }
    
    
    
    /**
     * 获取方法返回值上的某个位置的范型Class原型
     * 
     * @param i_Method
     * @param i_GenericsIndex   范型的位置
     * @return
     */
    public static GenericsReturn getGenericsReturn(Method i_Method ,int i_GenericsIndex)
    {
        GenericsReturn v_GR = new GenericsReturn();
        
        try
        {
            ParameterizedType v_PType = (ParameterizedType) i_Method.getGenericReturnType();
            Type              v_Type  = v_PType.getActualTypeArguments()[i_GenericsIndex];
            
            while ( v_Type instanceof ParameterizedType )
            {
                v_PType = (ParameterizedType) v_Type;
                v_GR.addMaster((Class<?>) (v_PType.getRawType()) );
                
                v_Type = v_PType.getActualTypeArguments()[i_GenericsIndex];
            }
            
            v_GR.setGenericType( (Class<?>)v_Type );
        }
        catch (Exception exce)
        {
            // Nothing.
        }
        
        return v_GR;
    }
    
    
    
    /**
     * 获取Java类的父类上的首个位置的范型Class原型
     * 
     * @param i_Class
     * @return
     */
    public static Class<?> getGenericsSuper(Class<?> i_Class)
    {
        return getGenericsSuper(i_Class ,0);
    }
    
    
    
    /**
     * 获取Java类的父类上的某个位置的范型Class原型
     * 
     * @param i_Class
     * @param i_GenericsIndex   范型的位置
     * @return
     */
    public static Class<?> getGenericsSuper(Class<?> i_Class ,int i_GenericsIndex)
    {
        try
        {
            ParameterizedType v_PType = (ParameterizedType) i_Class.getGenericSuperclass();
            Type              v_Type  = v_PType.getActualTypeArguments()[i_GenericsIndex];
            return (Class<?>)v_Type;
        }
        catch (Exception exce)
        {
            return null;
        }
    }
    
    
    
    public static Class<?> getGenerics(Class<?> i_Class ,int i_GenericsIndex)
    {
        try
        {
            ParameterizedType v_PType = (ParameterizedType) i_Class.getGenericInterfaces()[0];
            Type              v_Type  = v_PType.getActualTypeArguments()[i_GenericsIndex];
            return (Class<?>)v_Type;
        }
        catch (Exception exce)
        {
            return null;
        }
    }
    
    
    
    public static <V> Class<?> getGenerics(List<V> i_List)
    {
        try
        {
            return getGenerics(getMethods(i_List.getClass() ,"add" ,1).get(0));
        }
        catch (Exception exce)
        {
            return null;
        }
    }
    
	
	
	/**
	 * 获取默认 Setter 方法(入参个数只有一个的)
	 * 
	 * @param i_Class
	 * @param i_SetMethodName
	 * @param i_IsNorm
	 * @return
	 */
	public static Method getSetMethod(Class<?> i_Class ,String i_SetMethodName ,boolean i_IsNorm)
	{
		String v_SetMethodName      = i_SetMethodName.trim();
		String v_SetMethodNameFixed = null;
		
		if ( i_IsNorm )
		{
		    if ( v_SetMethodName.startsWith($FixedMethodName) )
		    {
		        v_SetMethodNameFixed = "set" + v_SetMethodName;
		        v_SetMethodName      = v_SetMethodName.substring(1);
		    }
		    else
		    {
		        v_SetMethodName = "set" + StringHelp.toUpperCaseByFirst(v_SetMethodName);
		    }
		}
		
		Method [] v_Methods = i_Class.getMethods();
		
		
		for (int i=0; i<v_Methods.length; i++)
		{
			if ( v_Methods[i].getName().equalsIgnoreCase(v_SetMethodName) )
			{
				if ( v_Methods[i].getParameterTypes().length == 1 )
				{
					return v_Methods[i];
				}
			}
		}
		
		// 当方法名称真的是get$xxx()、set$xxx()的形式,也是要尝试查询匹配一次的  2017-07-12
		if ( v_SetMethodNameFixed != null )
		{
    		for (int i=0; i<v_Methods.length; i++)
            {
                if ( v_Methods[i].getName().equalsIgnoreCase(v_SetMethodNameFixed) )
                {
                    if ( v_Methods[i].getParameterTypes().length == 1 )
                    {
                        return v_Methods[i];
                    }
                }
            }
		}
		
		return null;
	}
	
	
	
	/**
     * 获取多个重载的 Setter 方法集合(入参个数只有一个的)
     * 
     * @param i_Class
     * @param i_SetMethodName
     * @param i_IsNorm
     * @return
     */
    public static List<Method> getSetMethods(Class<?> i_Class ,String i_SetMethodName ,boolean i_IsNorm)
    {
        List<Method> v_Ret                = new ArrayList<Method>();
        String       v_SetMethodName      = i_SetMethodName.trim();
        String       v_SetMethodNameFixed = null;
        
        
        if ( i_IsNorm )
        {
            if ( v_SetMethodName.startsWith($FixedMethodName) )
            {
                v_SetMethodNameFixed = "set" + v_SetMethodName;
                v_SetMethodName      = v_SetMethodName.substring(1);
            }
            else
            {
                v_SetMethodName = "set" + StringHelp.toUpperCaseByFirst(v_SetMethodName);
            }
        }
        
        Method [] v_Methods = i_Class.getMethods();
        
        // 当方法名称真的是get$xxx()、set$xxx()的形式,也是要尝试查询匹配一次的  2017-07-12
        for (int i=0; i<v_Methods.length; i++)
        {
            // 不再区分大小写 2017-07-12
            if ( v_Methods[i].getName().equalsIgnoreCase(v_SetMethodName)
              || v_Methods[i].getName().equalsIgnoreCase(v_SetMethodNameFixed) )
            {
                if ( v_Methods[i].getParameterTypes().length == 1 )
                {
                    v_Ret.add(v_Methods[i]);
                }
            }
        }
        
        return v_Ret;
    }
    
    
    
    /**
     * 获取成对出现的 Getter、Setter 方法集合中的Getter方法
     * 
     * 返回结果是按方法名称排序的。
     * 
     * @param i_Class
     * @return         Map.key    为方法的短名称
     *                 Map.value  为方法对象
     */
    public static Map<String ,Method> getGetMethodsMS(Class<?> i_Class)
    {
        return getGetSetMethods(i_Class).get($Partition_GET);
    }
    
    
    
    /**
     * 获取成对出现的 Getter、Setter 方法集合中的Getter方法
     * 
     * 返回结果是按方法名称排序的。
     * 
     * 方法名称排序规则升级为:按方法对应的成员属性名称在类中的编程编写的顺序排序。
     * 
     * @author      ZhengWei(HY)
     * @createDate  2018-04-26
     * @version     v1.0
     *
     * @param i_Class
     * @return         Map.key    为方法的短名称
     *                 Map.value  为方法对象
     */
    public static Map<String ,Method> getGetMethodsMSByJava(Class<?> i_Class)
    {
        return getGetSetMethodsByJava(i_Class).get($Partition_GET);
    }
    
    
    
    /**
     * 获取成对出现的 Getter、Setter 方法集合中的Setter方法
     * 
     * 返回结果是按方法名称排序的。
     * 
     * @param i_Class
     * @return         Map.key    为方法的短名称
     *                 Map.value  为方法对象
     */
    public static Map<String ,Method> getSetMethodsMG(Class<?> i_Class)
    {
        return getGetSetMethods(i_Class).get($Partition_SET);
    }
    
    
    
    /**
     * 获取成对出现的 Getter、Setter 方法集合中的Setter方法
     * 
     * 返回结果是按方法名称排序的。
     * 
     * 方法名称排序规则升级为:按方法对应的成员属性名称在类中的编程编写的顺序排序。
     * 
     * @author      ZhengWei(HY)
     * @createDate  2018-04-26
     * @version     v1.0
     *
     * @param i_Class
     * @return         Map.key    为方法的短名称
     *                 Map.value  为方法对象
     */
    public static Map<String ,Method> getSetMethodsMGByJava(Class<?> i_Class)
    {
        return getGetSetMethodsByJava(i_Class).get($Partition_SET);
    }
    
    
    
    /**
     * 获取成对出现的 Getter、Setter 方法集合
     * 
     * 返回结果是按方法名称排序的。
     * 
     * @param i_Class
     * @return         TablePartitionRID.key    只有两种值GET或SET。is开头的方法,也在GET分区中。
     *                 TablePartitionRID.index  为方法的短名称
     *                 TablePartitionRID.value  为方法对象
     */
    public static TablePartitionRID<String ,Method> getGetSetMethods(Class<?> i_Class)
    {
        TablePartitionRID<String ,Method> v_Ret     = new TablePartitionRID<String ,Method>(2);
        Method []                         v_Methods = i_Class.getMethods();
        
        Arrays.sort(v_Methods ,MethodComparator.getInstance());
        
        // 先行过滤出Getter方法(包括is开头的方法)
        for (int i=0; i<v_Methods.length; i++)
        {
            Method v_Method = v_Methods[i];
            
            if ( v_Method.getParameterTypes().length == 0 )
            {
                if ( v_Method.getName().startsWith("get") )
                {
                    v_Ret.putRow($Partition_GET ,v_Method.getName().substring(3) ,v_Method);
                }
                else if ( v_Method.getName().startsWith("is") )
                {
                    v_Ret.putRow($Partition_GET ,v_Method.getName().substring(2) ,v_Method);
                }
            }
        }
        
        // 再过滤出Setter方法。并要求参数类型与Getter方法的类型一致
        for (int i=0; i<v_Methods.length; i++)
        {
            Method v_Method = v_Methods[i];
            
            if ( v_Method.getParameterTypes().length == 1 )
            {
                if ( v_Method.getName().startsWith("set") )
                {
                    String v_ShortName = v_Method.getName().substring(3);
                    Method v_Getter    = v_Ret.getRow($Partition_GET ,v_ShortName);
                    
                    if ( v_Getter != null )
                    {
                        if ( v_Method.getParameterTypes()[0] == v_Getter.getReturnType() )
                        {
                            v_Ret.putRow($Partition_SET ,v_ShortName ,v_Method);
                        }
                    }
                }
            }
        }
        
        // 核对是否成对出现
        List<String> v_ShortNames = Help.toListKeys(v_Ret.get($Partition_GET));
        for (String v_ShortName : v_ShortNames)
        {
            if ( v_Ret.getRow($Partition_SET ,v_ShortName) == null )
            {
                v_Ret.removeRow($Partition_GET ,v_ShortName);
            }
        }
        
        return v_Ret;
    }
    
    
    
    /**
     * 获取成对出现的 Getter、Setter 方法集合
     * 
     * 返回结果是按方法名称排序的。
     * 
     * 方法名称排序规则升级为:按方法对应的成员属性名称在类中的编程编写的顺序排序。
     * 
     * @author      ZhengWei(HY)
     * @createDate  2018-04-26
     * @version     v1.0
     *
     * @param i_Class
     * @return         TablePartitionRID.key    只有两种值GET或SET。is开头的方法,也在GET分区中。
     *                 TablePartitionRID.index  为方法的短名称
     *                 TablePartitionRID.value  为方法对象
     */
    public static TablePartitionRID<String ,Method> getGetSetMethodsByJava(Class<?> i_Class)
    {
        TablePartitionRID<String ,Method> v_Ret     = new TablePartitionRID<String ,Method>(2);
        Method []                         v_Methods = i_Class.getMethods();
        
        Arrays.sort(v_Methods ,new MethodFieldComparator(i_Class.getDeclaredFields()));
        
        // 先行过滤出Getter方法(包括is开头的方法)
        for (int i=0; i<v_Methods.length; i++)
        {
            Method v_Method = v_Methods[i];
            
            if ( v_Method.getParameterTypes().length == 0 )
            {
                if ( v_Method.getName().startsWith("get") )
                {
                    v_Ret.putRow($Partition_GET ,v_Method.getName().substring(3) ,v_Method);
                }
                else if ( v_Method.getName().startsWith("is") )
                {
                    v_Ret.putRow($Partition_GET ,v_Method.getName().substring(2) ,v_Method);
                }
            }
        }
        
        // 再过滤出Setter方法。并要求参数类型与Getter方法的类型一致
        for (int i=0; i<v_Methods.length; i++)
        {
            Method v_Method = v_Methods[i];
            
            if ( v_Method.getParameterTypes().length == 1 )
            {
                if ( v_Method.getName().startsWith("set") )
                {
                    String v_ShortName = v_Method.getName().substring(3);
                    Method v_Getter    = v_Ret.getRow($Partition_GET ,v_ShortName);
                    
                    if ( v_Getter != null )
                    {
                        if ( v_Method.getParameterTypes()[0] == v_Getter.getReturnType() )
                        {
                            v_Ret.putRow($Partition_SET ,v_ShortName ,v_Method);
                        }
                    }
                }
            }
        }
        
        // 核对是否成对出现
        List<String> v_ShortNames = Help.toListKeys(v_Ret.get($Partition_GET));
        for (String v_ShortName : v_ShortNames)
        {
            if ( v_Ret.getRow($Partition_SET ,v_ShortName) == null )
            {
                v_Ret.removeRow($Partition_GET ,v_ShortName);
            }
        }
        
        return v_Ret;
    }
	
	
	
	/**
	 * 获取默认 Getter 方法(无入参的)
	 * 
	 * @param i_Class
	 * @param i_GetMethodName
	 * @param i_IsNorm
	 * @return
	 */
	public static Method getGetMethod(Class<?> i_Class ,String i_GetMethodName ,boolean i_IsNorm)
	{
		String v_GetMethodName_Get       = i_GetMethodName.trim();
		String v_GetMethodName_Is        = i_GetMethodName.trim();
		String v_GetMethodName_Fixed_Get = null;
        String v_GetMethodName_Fixed_Is  = null;
		
		if ( i_IsNorm )
		{
		    if ( v_GetMethodName_Get.startsWith($FixedMethodName) )
		    {
		        v_GetMethodName_Fixed_Get = "get" + v_GetMethodName_Get;
		        v_GetMethodName_Fixed_Is  = "is"  + v_GetMethodName_Is;
		        v_GetMethodName_Get       = v_GetMethodName_Get.substring(1);
                v_GetMethodName_Is        = v_GetMethodName_Is.substring(1);
		    }
		    else
		    {
		        v_GetMethodName_Get = "get" + StringHelp.toUpperCaseByFirst(v_GetMethodName_Get);
                v_GetMethodName_Is  = "is"  + StringHelp.toUpperCaseByFirst(v_GetMethodName_Is);
		    }
		}
		
		Method [] v_Methods = i_Class.getMethods();
		
		
		for (int i=0; i<v_Methods.length; i++)
		{
			if ( v_Methods[i].getName().equalsIgnoreCase(v_GetMethodName_Get)
			  || v_Methods[i].getName().equalsIgnoreCase(v_GetMethodName_Is) )
			{
				if ( v_Methods[i].getParameterTypes().length == 0 )
				{
					return v_Methods[i];
				}
			}
		}
		
		// 当方法名称真的是get$xxx()、set$xxx()的形式,也是要尝试查询匹配一次的  2017-07-12
		if ( v_GetMethodName_Fixed_Get != null )
		{
		    for (int i=0; i<v_Methods.length; i++)
	        {
	            if ( v_Methods[i].getName().equalsIgnoreCase(v_GetMethodName_Fixed_Get)
	              || v_Methods[i].getName().equalsIgnoreCase(v_GetMethodName_Fixed_Is) )
	            {
	                if ( v_Methods[i].getParameterTypes().length == 0 )
	                {
	                    return v_Methods[i];
	                }
	            }
	        }
		}
		
		return null;
	}
    
    
    
    /**
     * 获取前缀相同的方法
     * 
     * 只获取"本类自己"的方法
     * 
     * @param i_Class
     * @param i_MethodPrefixName
     * @return
     */
    public static List<Method> getStartMethods(Class<?> i_Class ,String i_MethodPrefixName)
    {
        List<Method> v_Ret     = new ArrayList<Method>();
        Method []    v_Methods = i_Class.getMethods();
        
        for (int i=0; i<v_Methods.length; i++)
        {
            // 只获取"本类自己"的方法
            if ( !Modifier.isNative(v_Methods[i].getModifiers()) )
            {
                if ( v_Methods[i].getName().startsWith(i_MethodPrefixName) )
                {
                    v_Ret.add(v_Methods[i]);
                }
            }
        }
        
        return v_Ret;
    }
    
    
    
    /**
     * 获取多个前缀相同的方法
     * 
     * 只获取"本类自己"的方法
     * 
     * @param i_Class
     * @param i_MethodPrefixNames
     * @return
     */
    public static List<Method> getStartMethods(Class<?> i_Class ,String [] i_MethodPrefixNames)
    {
        List<Method> v_Ret     = new ArrayList<Method>();
        Method []    v_Methods = i_Class.getMethods();
        
        for (int i=0; i<v_Methods.length; i++)
        {
            // 只获取"本类自己"的方法
            if ( !Modifier.isNative(v_Methods[i].getModifiers()) )
            {
                for (int x=0; x<i_MethodPrefixNames.length; x++)
                {
                    if ( v_Methods[i].getName().startsWith(i_MethodPrefixNames[x]) )
                    {
                        v_Ret.add(v_Methods[i]);
                        break;
                    }
                }
            }
        }
        
        return v_Ret;
    }
    
    
    
    /**
     * 获取前缀相同,入参参数匹配的方法
     * 
     * 只获取"本类自己"的方法
     * 
     * @param i_Class
     * @param i_MethodPrefixName  参数名称前缀 
     * @param i_ParamSize         参数个数
     * @return
     */
    public static List<Method> getStartMethods(Class<?> i_Class ,String i_MethodPrefixName ,int i_ParamSize)
    {
        List<Method> v_Ret     = new ArrayList<Method>();
        Method []    v_Methods = i_Class.getMethods();
        
        
        for (int i=0; i<v_Methods.length; i++)
        {
            // 只获取"本类自己"的方法
            if ( !Modifier.isNative(v_Methods[i].getModifiers()) )
            {
                if ( v_Methods[i].getParameterTypes().length == i_ParamSize )
                {
                    if ( v_Methods[i].getName().startsWith(i_MethodPrefixName) )
                    {
                        v_Ret.add(v_Methods[i]);
                    }
                }
            }
        }
        
        return v_Ret;
    }
    
    
    
    /**
     * 获取多个前缀相同,入参参数匹配的方法
     * 
     * 只获取"本类自己"的方法
     * 
     * @param i_Class
     * @param i_MethodPrefixName  参数名称前缀 
     * @param i_ParamSize         参数个数
     * @return
     */
    public static List<Method> getStartMethods(Class<?> i_Class ,String [] i_MethodPrefixNames ,int i_ParamSize)
    {
        List<Method> v_Ret     = new ArrayList<Method>();
        Method []    v_Methods = i_Class.getMethods();
        
        
        for (int i=0; i<v_Methods.length; i++)
        {
            // 只获取"本类自己"的方法
            if ( !Modifier.isNative(v_Methods[i].getModifiers()) )
            {
                if ( v_Methods[i].getParameterTypes().length == i_ParamSize )
                {
                    for (int x=0; x<i_MethodPrefixNames.length; x++)
                    {
                        if ( v_Methods[i].getName().startsWith(i_MethodPrefixNames[x]) )
                        {
                            v_Ret.add(v_Methods[i]);
                            break;
                        }
                    }
                }
            }
        }
        
        return v_Ret;
    }
	
	
	
	/**
	 * 获取某一方法名称的所有方法对象。包括重载的多个方法
	 * 
	 * @param i_Class
	 * @param i_MethodName
	 * @return
	 */
	public static List<Method> getMethods(Class<?> i_Class ,String i_MethodName)
	{
		List<Method> v_Ret     = new ArrayList<Method>();
		Method []    v_Methods = i_Class.getMethods();
		
		for (int i=0; i<v_Methods.length; i++)
		{
		    // 不再区分大小写 2017-07-12
			if ( v_Methods[i].getName().equalsIgnoreCase(i_MethodName) )
			{
				v_Ret.add(v_Methods[i]);
			}
		}
		
		return v_Ret;
	}
	
	
	
	/**
	 * 获取某一方法名称的所有方法对象。包括重载的多个方法。(忽然大小的匹配)
	 * 
	 * @param i_Class
	 * @param i_MethodName
	 * @return
	 */
	public static List<Method> getMethodsIgnoreCase(Class<?> i_Class ,String i_MethodName)
	{
		List<Method> v_Ret     = new ArrayList<Method>();
		Method []    v_Methods = i_Class.getMethods();
		
		for (int i=0; i<v_Methods.length; i++)
		{
			if ( v_Methods[i].getName().equalsIgnoreCase(i_MethodName) )
			{
				v_Ret.add(v_Methods[i]);
			}
		}
		
		return v_Ret;
	}
    
    
    
    /**
     * 获取指定参数个数的所有方法对象。
     * 
     * 只获取"本类自己"的方法
     * 只获取公共方法,即 Public 方法
     * 
     * @param i_Class
     * @param i_ParamSize
     * @return
     */
    public static List<Method> getMethods(Class<?> i_Class ,int i_ParamSize)
    {
        List<Method> v_Ret     = new ArrayList<Method>();
        Method []    v_Methods = i_Class.getDeclaredMethods();
        
        for (int i=0; i<v_Methods.length; i++)
        {
            Method v_Method = v_Methods[i];
            
            if ( v_Method.getParameterTypes().length == i_ParamSize )
            {   
                if ( Modifier.isPublic(v_Method.getModifiers()) )
                {
                    v_Ret.add(v_Methods[i]);
                }
            }
        }
        
        return v_Ret;
    }
    
    
    
    /**
     * 获取排除某些前缀的成员方法
     * 
     * 获取本类以及父类或者父接口中所有的公共方法(public修饰符修饰的)
     * 
     * @author      ZhengWei(HY)
     * @createDate  2020-01-14
     * @version     v1.0
     *
     * @param i_Class              Java元类
     * @param i_StartMethodNames   不区分大小写配对
     * @return
     */
    public static List<Method> getMethodsExcludeStart(Class<?> i_Class ,String [] i_StartMethodNames)
    {
        List<Method> v_Ret     = new ArrayList<Method>();
        Method []    v_Methods = i_Class.getMethods();
        String []    v_Starts  = new String[i_StartMethodNames.length];
        
        if ( Help.isNull(i_StartMethodNames) )
        {
            return v_Ret;
        }
        
        // 不再区分大小写
        for (int i=0; i<i_StartMethodNames.length; i++)
        {
            v_Starts[i] = i_StartMethodNames[i].toLowerCase();
        }
        
        for (int i=0; i<v_Methods.length; i++)
        {
            String v_MName = v_Methods[i].getName().toLowerCase();
            
            if ( !StringHelp.isStartsWith(v_MName ,v_Starts) )
            {
                v_Ret.add(v_Methods[i]);
            }
        }
        
        return v_Ret;
    }
    
    
    
    /**
     * 获取方法入参参数上的指定类型的注解
     * 
     * 1. 方法入参有三个,其中两个参数有注解。返回集合元素为三个,未注解参数的集合元素为null。
     * 
     * @author      ZhengWei(HY)
     * @createDate  2017-12-18
     * @version     v1.0
     *
     * @param i_Method
     * @param i_AnnotationClass
     * @return                   所有入参数均无注解时,返回null
     */
    @SuppressWarnings("unchecked")
    public static <A extends Annotation> List<A> getParameterAnnotations(Method i_Method ,Class<A> i_AnnotationClass)
    {
        List<A> v_Params = null;
        int     v_PCount = 0;
        
        Annotation[][] v_PAnnos = i_Method.getParameterAnnotations();
        if ( !Help.isNull(v_PAnnos) )
        {
            v_Params = new ArrayList<A>(i_Method.getParameterTypes().length);
            
            for (int xp=0; xp<v_PAnnos.length; xp++)
            {
                A v_Temp = null;
                
                for (int xpAI=0; xpAI<v_PAnnos[xp].length; xpAI++)
                {
                    if ( i_AnnotationClass == v_PAnnos[xp][xpAI].annotationType() )
                    {
                        v_Temp = (A)v_PAnnos[xp][xpAI];
                        v_PCount++;
                        break;
                    }
                }
                
                v_Params.add(v_Temp);
            }
            
            if ( v_PCount <= 0 )
            {
                v_Params = null;
            }
        }
        
        return v_Params;
    }
    
    
    
    /**
     * 获取指定参数个数的,并且为某一注解的所有方法对象
     * 
     * 只获取"本类自己"的方法
     * 只获取公共方法,即 Public 方法
     * 获取任一参数个数的方法
     * 
     * @param i_Class
     * @param i_AnnotationClass   注解类型的元类型
     * @return
     */
    public static List<Method> getAnnotationMethods(Class<?> i_Class ,Class<? extends Annotation> i_AnnotationClass)
    {
        return getAnnotationMethods(i_Class ,i_AnnotationClass ,-1);
    }
    
    
    
    /**
     * 获取指定参数个数的,并且为某一注解的所有方法对象
     * 
     * 只获取"本类自己"的方法
     * 只获取公共方法,即 Public 方法
     * 
     * @param i_Class
     * @param i_AnnotationClass   注解类型的元类型
     * @param i_ParamSize         参数个数。小于0表示:无参数个数限制
     * @return
     */
    public static List<Method> getAnnotationMethods(Class<?> i_Class ,Class<? extends Annotation> i_AnnotationClass ,int i_ParamSize)
    {
        List<Method> v_Ret = new ArrayList<Method>();
        
        try
        {
            Method [] v_Methods = i_Class.getDeclaredMethods();
            
            // 无参数个数限制
            if ( i_ParamSize < 0 )
            {
                for (int i=0; i<v_Methods.length; i++)
                {
                    Method v_Method = v_Methods[i];
                    
                    if ( Modifier.isPublic(v_Method.getModifiers()) )
                    {
                        if ( v_Method.isAnnotationPresent(i_AnnotationClass) )
                        {
                            v_Ret.add(v_Method);
                        }
                    }
                }
            }
            else
            {
                for (int i=0; i<v_Methods.length; i++)
                {
                    Method v_Method = v_Methods[i];
                    
                    if ( v_Method.getParameterTypes().length == i_ParamSize )
                    {   
                        if ( Modifier.isPublic(v_Method.getModifiers()) )
                        {
                            if ( v_Method.isAnnotationPresent(i_AnnotationClass) )
                            {
                                v_Ret.add(v_Method);
                            }
                        }
                    }
                }
            }
        }
        catch (Throwable exce)
        {
            // 2018-01-29 扫描项目所有类时,当发现某一类引用的类不存在时,只错误提示不中断服务。
            System.err.println("Error: " + i_Class.getName() + ": " + exce.getMessage() + " " + exce.getClass().getName());
        }
        
        return v_Ret;
    }
	
	
	
	/**
	 * 获取某一方法名称的所有方法对象。包括重载的多个方法
	 * 
	 * @param i_Class
	 * @param i_MethodName
	 * @param i_ParamSize
	 * @return
	 */
	public static List<Method> getMethods(Class<?> i_Class ,String i_MethodName ,int i_ParamSize)
	{
		List<Method> v_Ret     = new ArrayList<Method>();
		Method []    v_Methods = i_Class.getMethods();
		
		for (int i=0; i<v_Methods.length; i++)
		{
		    // 不再区分大小写 2017-07-12
			if ( v_Methods[i].getName().equalsIgnoreCase(i_MethodName) )
			{
				if ( v_Methods[i].getParameterTypes().length == i_ParamSize )
				{
					v_Ret.add(v_Methods[i]);
				}
			}
		}
		
		return v_Ret;
	}
	
	
	
	/**
	 * 获取某一方法名称的所有方法对象。包括重载的多个方法。(忽然大小的匹配)
	 * 
	 * @param i_Class
	 * @param i_MethodName
	 * @param i_ParamSize
	 * @return
	 */
	public static List<Method> getMethodsIgnoreCase(Class<?> i_Class ,String i_MethodName ,int i_ParamSize)
	{
		List<Method> v_Ret     = new ArrayList<Method>();
		Method []    v_Methods = i_Class.getMethods();
		
		for (int i=0; i<v_Methods.length; i++)
		{
			if ( v_Methods[i].getName().equalsIgnoreCase(i_MethodName) )
			{
				if ( v_Methods[i].getParameterTypes().length == i_ParamSize )
				{
					v_Ret.add(v_Methods[i]);
				}
			}
		}
		
		return v_Ret;
	}
	
	
	
	/**
	 * 向数据库表插入数据时,通过Java生成主键的功能。与SQL占位符配合使用。
	 * 
	 * @author      ZhengWei(HY)
	 * @createDate  2016-03-18
	 * @version     v1.0
	 *
	 * @return
	 */
	public static MethodReflect getMethodReflectUUID()
	{
	    MethodReflectUUID v_MRUUID = MethodReflectUUID.getInstance();
	    
	    try
        {
            return new MethodReflect(v_MRUUID ,v_MRUUID.getClass().getMethod("getUUID" ,new Class[]{}));
        }
        catch (Exception e)
        {
            throw new java.lang.InstantiationError("");
        }
	}
	
	
	
	/**
     * 从Map集合中取值。实现xxx.yyy.www(或getXxx.getYyy.getWww)全路径的解释
     * 
     * @author      ZhengWei(HY)
     * @createDate  2016-07-29
     * @version     v1.0
     *
     * @param i_MapValues  Map集合
     * @param i_MethodURL  方法全路径(不区分大小写)
     * @return
     */
    @SuppressWarnings("unchecked")
    public static Object getMapValue(Map<String ,?> i_MapValues ,String i_MethodURL)
    {
        String [] v_MethodURLArr = i_MethodURL.split("\\.");
        if ( v_MethodURLArr.length <= 1 )
        {
            return Help.getValueIgnoreCase(i_MapValues ,i_MethodURL);
        }
        
        Object v_MapValue = Help.getValueIgnoreCase(i_MapValues ,v_MethodURLArr[0]);
        if ( v_MapValue == null )
        {
            return null;
        }
        
        String v_ChildMethodURL = StringHelp.replaceAll(i_MethodURL ,v_MethodURLArr[0] + "." ,"");
        
        if ( MethodReflect.isExtendImplement(v_MapValue ,Map.class) )
        {
            return getMapValue((Map<String ,?>)v_MapValue ,v_ChildMethodURL);
        }
        else if ( MethodReflect.class.equals(v_MapValue.getClass()) )
        {
            return v_MapValue;
        }
        else
        {
            MethodReflect v_MethodReflect = null;
            
            try
            {
                v_MethodReflect = new MethodReflect(v_MapValue ,v_ChildMethodURL ,true ,MethodReflect.$NormType_Getter);
                return v_MethodReflect.invoke();
            }
            catch (Exception exce)
            {
                exce.printStackTrace();
            }
            
            return null;
        }
    }
    
    
    
    /**
     * 根据方法的入参类型,获取某一具体的方法。
     * 
     * 支持对重载方法的判定。对每参数类型都进行比较确认惟一的执行方法
     * 
     * 从org.hy.common.Execute类中提炼而出。
     * 
     * @author      ZhengWei(HY)
     * @createDate  2017-01-16
     * @version     v1.0
     *
     * @param i_Instance      实例对象 
     * @param i_MethodName    方法名称(区分大小写)
     * @param i_MethodParams  方法的入参
     * @return
     */
    public static Method getMethod(Object i_Instance ,String i_MethodName ,Object [] i_MethodParams)
    {
        return getMethod(i_Instance.getClass() ,i_MethodName ,i_MethodParams);
    }
    
    
    
    /**
     * 根据方法的入参类型,获取某一具体的方法。
     * 
     * 支持对重载方法的判定。对每参数类型都进行比较确认惟一的执行方法
     * 
     * 从org.hy.common.Execute类中提炼而出。
     * 
     * @author      ZhengWei(HY)
     * @createDate  2017-01-16
     * @version     v1.0
     *
     * @param i_Class         对象类型 
     * @param i_MethodName    方法名称(不区分大小写)
     * @param i_MethodParams  方法的入参
     * @return
     */
    public static Method getMethod(Class<?> i_Class ,String i_MethodName ,Object [] i_MethodParams)
    {
        Method []    v_Methods   = i_Class.getMethods();
        List<Method> v_OKMethods = new ArrayList<Method>();
        Method       v_Method    = null;
        
        for (int i=0; i<v_Methods.length; i++)
        {
            v_Method = v_Methods[i];
            
            // 不再区分大小写 2017-07-12
            if ( v_Method.getName().equalsIgnoreCase(i_MethodName) )
            {
                if ( v_Method.getParameterTypes().length == i_MethodParams.length )
                {
                    boolean v_PTypeOK = true;
                    
                    // 先过滤出符合条件的方法  ZhengWei(HY) Add 2017-01-06
                    for (int v_PIndex=0; v_PIndex<i_MethodParams.length; v_PIndex++)
                    {
                        if ( i_MethodParams[v_PIndex].getClass() != v_Method.getParameterTypes()[v_PIndex] 
                          && !MethodReflect.isExtendImplement(i_MethodParams[v_PIndex] ,v_Method.getParameterTypes()[v_PIndex]) )
                        {
                            if ( int    .class == v_Method.getParameterTypes()[v_PIndex] 
                              && Integer.class == i_MethodParams[v_PIndex].getClass() )
                            {
                                // Nothing.
                            }
                            else if ( double.class == v_Method.getParameterTypes()[v_PIndex] 
                                   && Double.class == i_MethodParams[v_PIndex].getClass() )
                            {
                                // Nothing.
                            }
                            else if ( float.class == v_Method.getParameterTypes()[v_PIndex] 
                                   && Float.class == i_MethodParams[v_PIndex].getClass() )
                            {
                                // Nothing.
                            }
                            else if ( long.class == v_Method.getParameterTypes()[v_PIndex] 
                                   && Long.class == i_MethodParams[v_PIndex].getClass() )
                            {
                                // Nothing.
                            }
                            else if ( boolean.class == v_Method.getParameterTypes()[v_PIndex] 
                                   && Boolean.class == i_MethodParams[v_PIndex].getClass() )
                            {
                                // Nothing.
                            }
                            else if ( BigDecimal.class == i_MethodParams[v_PIndex].getClass() )
                            {
                                // Nothing.
                            }
                            else if ( short.class == v_Method.getParameterTypes()[v_PIndex] 
                                   && Short.class == i_MethodParams[v_PIndex].getClass() )
                            {
                                // Nothing.
                            }
                            else if ( byte.class == v_Method.getParameterTypes()[v_PIndex] 
                                   && Byte.class == i_MethodParams[v_PIndex].getClass() )
                            {
                                // Nothing.
                            }
                            else if ( char     .class == v_Method.getParameterTypes()[v_PIndex] 
                                   && Character.class == i_MethodParams[v_PIndex].getClass() )
                            {
                                // Nothing.
                            }
                            else
                            {
                                v_PTypeOK = false;
                                break;
                            }
                        }
                    }
                    
                    if ( !v_PTypeOK )
                    {
                        continue;
                    }
                    
                    v_OKMethods.add(v_Method);
                }
            }
        }
        
        // 再去除多余的方法:其参数为 Object 类型的方法  ZhengWei(HY) Add 2017-01-06
        for (int v_PIndex=0; v_PIndex<i_MethodParams.length; v_PIndex++)
        {
            if ( v_OKMethods.size() <= 1 )
            {
                break;
            }
            
            for (int i=v_OKMethods.size()-1; i>=0; i--)
            {
                v_Method = v_OKMethods.get(i);
                
                if ( v_OKMethods.size() >= 2 )
                {
                    if ( v_Method.getParameterTypes()[v_PIndex] == Object.class )
                    {
                        v_OKMethods.remove(i);
                    }
                }
                else
                {
                    break;
                }
            }
        }
        
        if ( v_OKMethods.size() == 1 )
        {
            return v_OKMethods.get(0);
        }
        else
        {
            return null;
        }
    }
    
    
    
    /**
     * 调用对象的Setter赋值。
     * 
     * 可将字符串表达形式的任何值,转换为真实的Java类型后,调用对象的Setter赋值。
     * 
     * 从XJava中的提炼出来。
     * 
     * @author      ZhengWei(HY)
     * @createDate  2017-11-24
     * @version     v1.0
     *
     * @param i_SetMethod  方法对象
     * @param i_Instance   实例对象
     * @param i_Value      可以为字符串表达形式的任何值。如下情况
     *                         1. i_Value = "true",当成员属性为Boolean类型时,将转为 true 进行赋值。
     *                         2. i_Value = "true",当成功属性为String 类型时,将转为"true"进行赋值。
     * @param i_Replaces   须替换的字符。注:只对String、Class两类型生效。
     * @throws IllegalAccessException
     * @throws IllegalArgumentException
     * @throws InvocationTargetException
     * @throws ClassNotFoundException
     */
    public static void invokeSet(Method i_SetMethod ,Object i_Instance ,Object i_Value) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, ClassNotFoundException
    {
        invokeSet(i_SetMethod ,i_Instance ,i_Value ,null);
    }
    
    
    
    /**
     * 调用对象的Setter赋值。
     * 
     * 可将字符串表达形式的任何值,转换为真实的Java类型后,调用对象的Setter赋值。
     * 
     * 从XJava中的提炼出来。
     * 
     * @author      ZhengWei(HY)
     * @createDate  2017-11-24
     * @version     v1.0
     *
     * @param i_SetMethod  方法对象
     * @param i_Instance   实例对象
     * @param i_Value      可以为字符串表达形式的任何值。如下情况
     *                         1. i_Value = "true",当成员属性为Boolean类型时,将转为 true 进行赋值。
     *                         2. i_Value = "true",当成功属性为String 类型时,将转为"true"进行赋值。
     * @param i_Replaces   须替换的字符。注:只对String、Class两类型生效。
     * @throws IllegalAccessException
     * @throws IllegalArgumentException
     * @throws InvocationTargetException
     * @throws ClassNotFoundException
     */
    @SuppressWarnings("unchecked")
    public static void invokeSet(Method i_SetMethod ,Object i_Instance ,Object i_Value ,Map<String ,String> i_Replaces) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, ClassNotFoundException
    {
        Class<?> v_ParamType = i_SetMethod.getParameterTypes()[0];
        
        // 这里只对String、枚举、日期等特殊的类进行处理,其它的都是类型,而不是类
        if ( String.class == v_ParamType )
        {
            if ( i_Value != null )
            {
                i_SetMethod.invoke(i_Instance ,StringHelp.replaceAll(i_Value.toString() ,i_Replaces ,false));
            }
            else
            {
                i_SetMethod.invoke(i_Instance ,(String)null);
            }
        }
        else if ( MethodReflect.isExtendImplement(v_ParamType ,Enum.class) )
        {
            if ( i_Value != null && !Help.isNull(i_Value.toString()) )
            {
                Enum<?> [] v_EnumValues = StaticReflect.getEnums((Class<? extends Enum<?>>) v_ParamType);
                String     v_Value      = i_Value.toString();
                
                // ZhengWei(HY) Add 2018-05-08  支持枚举toString()的匹配 
                for (Enum<?> v_Enum : v_EnumValues)
                {
                    if ( v_Value.equalsIgnoreCase(v_Enum.toString()) )
                    {
                        i_SetMethod.invoke(i_Instance ,v_Enum);
                        return;
                    }
                }
                
                // ZhengWei(HY) Add 2017-10-31  支持枚举名称的匹配 
                for (Enum<?> v_Enum : v_EnumValues)
                {
                    if ( v_Value.equalsIgnoreCase(v_Enum.name()) )
                    {
                        i_SetMethod.invoke(i_Instance ,v_Enum);
                        return;
                    }
                }
                
                // 尝试用枚举值匹配 
                if ( Help.isNumber(v_Value) )
                {
                    int v_IntValue = Integer.parseInt(v_Value.trim());
                    if ( 0 <= v_IntValue && v_IntValue < v_EnumValues.length )
                    {
                        i_SetMethod.invoke(i_Instance ,v_EnumValues[v_IntValue]);
                    }
                }
            }
        }
        else if ( Date.class == v_ParamType )
        {
            // 以下每个if分支的空判定,只能写在此处,不能统一提炼,预防Java对象.toString()是空的情况。
            if ( i_Value != null && !Help.isNull(i_Value.toString()) )
            {
                i_SetMethod.invoke(i_Instance ,new Date(i_Value.toString()));
            }
            else
            {
                i_SetMethod.invoke(i_Instance ,(Date)null);
            }
        }
        else if ( java.util.Date.class == v_ParamType )
        {
            if ( i_Value != null && !Help.isNull(i_Value.toString()) )
            {
                i_SetMethod.invoke(i_Instance ,(new Date(i_Value.toString()).getDateObject()));
            }
            else
            {
                i_SetMethod.invoke(i_Instance ,(java.util.Date)null);
            }
        }
        // 添加对数据库时间的转换 Add ZhengWei(HY) 2018-05-15 
        else if ( Timestamp.class == v_ParamType )
        {
            if ( i_Value != null && !Help.isNull(i_Value.toString()) )
            {
                i_SetMethod.invoke(i_Instance ,(new Date(i_Value.toString()).getSQLTimestamp()));
            }
            else
            {
                i_SetMethod.invoke(i_Instance ,(Timestamp)null);
            }
        }
        else if ( int.class == v_ParamType )
        {
            if ( i_Value != null && !Help.isNull(i_Value.toString()) )
            {
                i_SetMethod.invoke(i_Instance ,Integer.parseInt(i_Value.toString()));
            }
        }
        else if ( Integer.class == v_ParamType )
        {
            if ( i_Value != null && !Help.isNull(i_Value.toString()) )
            {
                i_SetMethod.invoke(i_Instance ,Integer.valueOf(i_Value.toString()));
            }
            else
            {
                i_SetMethod.invoke(i_Instance ,(Integer)null);
            }
        }
        else if ( boolean.class == v_ParamType )
        {
            if ( i_Value != null && !Help.isNull(i_Value.toString()) )
            {
                i_SetMethod.invoke(i_Instance ,Boolean.parseBoolean(i_Value.toString()));
            }
        }
        else if ( Boolean.class == v_ParamType )
        {
            if ( i_Value != null && !Help.isNull(i_Value.toString()) )
            {
                i_SetMethod.invoke(i_Instance ,Boolean.valueOf(i_Value.toString()));
            }
            else
            {
                i_SetMethod.invoke(i_Instance ,(Boolean)null);
            }
        }
        else if ( double.class == v_ParamType )
        {
            if ( i_Value != null && !Help.isNull(i_Value.toString()) )
            {
                i_SetMethod.invoke(i_Instance ,Double.parseDouble(i_Value.toString()));
            }
        }
        else if ( Double.class == v_ParamType )
        {
            if ( i_Value != null && !Help.isNull(i_Value.toString()) )
            {
                i_SetMethod.invoke(i_Instance ,Double.valueOf(i_Value.toString()));
            }
            else
            {
                i_SetMethod.invoke(i_Instance ,(Double)null);
            }
        }
        else if ( float.class == v_ParamType )
        {
            if ( i_Value != null && !Help.isNull(i_Value.toString()) )
            {
                i_SetMethod.invoke(i_Instance ,Float.parseFloat(i_Value.toString()));
            }
        }
        else if ( Float.class == v_ParamType )
        {
            if ( i_Value != null && !Help.isNull(i_Value.toString()) )
            {
                i_SetMethod.invoke(i_Instance ,Float.valueOf(i_Value.toString()));
            }
            else
            {
                i_SetMethod.invoke(i_Instance ,(Float)null);
            }
        }
        else if ( long.class == v_ParamType )
        {
            if ( i_Value != null && !Help.isNull(i_Value.toString()) )
            {
                i_SetMethod.invoke(i_Instance ,Long.parseLong(i_Value.toString()));
            }
        }
        else if ( Long.class == v_ParamType )
        {
            if ( i_Value != null && !Help.isNull(i_Value.toString()) )
            {
                i_SetMethod.invoke(i_Instance ,Long.valueOf(i_Value.toString()));
            }
            else
            {
                i_SetMethod.invoke(i_Instance ,(Long)null);
            }
        }
        else if ( BigDecimal.class == v_ParamType )
        {
            if ( i_Value != null && !Help.isNull(i_Value.toString()) )
            {
                i_SetMethod.invoke(i_Instance ,new BigDecimal(i_Value.toString()));
            }
            else
            {
                i_SetMethod.invoke(i_Instance ,(BigDecimal)null);
            }
        }
        else if ( short.class == v_ParamType )
        {
            if ( i_Value != null && !Help.isNull(i_Value.toString()) )
            {
                i_SetMethod.invoke(i_Instance ,Short.parseShort(i_Value.toString()));
            }
        }
        else if ( Short.class == v_ParamType )
        {
            if ( i_Value != null && !Help.isNull(i_Value.toString()) )
            {
                i_SetMethod.invoke(i_Instance ,Short.valueOf(i_Value.toString()));
            }
            else
            {
                i_SetMethod.invoke(i_Instance ,(Short)null);
            }
        }
        else if ( byte.class == v_ParamType )
        {
            if ( i_Value != null && !Help.isNull(i_Value.toString()) )
            {
                i_SetMethod.invoke(i_Instance ,Byte.parseByte(i_Value.toString()));
            }
        }
        else if ( Byte.class == v_ParamType )
        {
            if ( i_Value != null && !Help.isNull(i_Value.toString()) )
            {
                i_SetMethod.invoke(i_Instance ,Byte.valueOf(i_Value.toString()));
            }
            else
            {
                i_SetMethod.invoke(i_Instance ,(Byte)null);
            }
        }
        else if ( char.class == v_ParamType )
        {
            // 此不要加 .trim() 方法
            if ( i_Value != null && i_Value.toString() != null && !"".equals(i_Value.toString()) )
            {
                i_SetMethod.invoke(i_Instance ,i_Value.toString().charAt(0));
            }
        }
        else if ( Character.class == v_ParamType )
        {
            // 此不要加 .trim() 方法
            if ( i_Value != null && i_Value.toString() != null && !"".equals(i_Value.toString()) )
            {
                i_SetMethod.invoke(i_Instance ,i_Value.toString().charAt(0));
            }
            else
            {
                i_SetMethod.invoke(i_Instance ,(Character)null);
            }
        }
        else if ( Class.class == v_ParamType )
        {
            if ( i_Value != null && !Help.isNull(i_Value.toString()) )
            {
                i_SetMethod.invoke(i_Instance ,Help.forName(StringHelp.replaceAll(i_Value.toString().trim() ,i_Replaces ,false)));
            }
            else
            {
                i_SetMethod.invoke(i_Instance ,(Class<?>)null);
            }
        }
        else
        {
            i_SetMethod.invoke(i_Instance ,i_Value);
        }
    }
    
    
    
    /**
     * 方法的反射
     * 
     * 可实现xxx.yyy.www(或getXxx.getYyy.setWww)全路径的解释
     * 可实现xxx.yyy.www(或getXxx.getYyy.getWww)全路径的解释
     * 
     * @author      ZhengWei(HY)
     * @createDate  2017-03-17
     * @version     v1.0
     *              v2.0  2017-06-15  添加:i_MethodURL方法全路径中的每个方法名称,不再区分大小写
     * 
     * @param i_Class       最上层的对象类型
     * @param i_MethodURL   方法全路径
     * @param i_IsNorm      方法全路径是否符合规范
     * @param i_NormType    规范类型
     * 
     * @throws SecurityException
     * @throws IllegalArgumentException
     * @throws NoSuchMethodException
     * @throws IllegalAccessException
     * @throws InvocationTargetException
     */
    public MethodReflect(Class<?> i_Class ,String i_MethodURL ,boolean i_IsNorm ,int i_NormType) throws SecurityException, IllegalArgumentException, NoSuchMethodException, IllegalAccessException, InvocationTargetException
    {
        this.classes       = new ArrayList<Class<?>>();
        this.instances     = null;
        this.methods       = new ArrayList<List<MethodInfo>>();
        this.methodsParams = new ArrayList<List<String>>();
        this.methodURL     = i_MethodURL.trim();
        this.methodNames   = this.methodURL.replace("." ,"@").split("@");
        this.isNorm        = i_IsNorm;
        this.normType      = i_NormType;
        
        this.classes.add(i_Class);
        
        this.parser();
    }
    
    
    
    /**
     * 方法的反射
     * 
     * 可实现xxx.yyy.www(或getXxx.getYyy.setWww)全路径的解释
     * 可实现xxx.yyy.www(或getXxx.getYyy.getWww)全路径的解释
     * 
     * @author      ZhengWei(HY)
     * @createDate  2017-03-17
     * @version     v1.0
     *              v2.0  2017-06-15  添加:i_MethodURL方法全路径中的每个方法名称,不再区分大小写
     * 
     * @param i_Class       最上层的对象类型
     * @param i_MethodURL   方法全路径
     * @param i_NormType    规范类型
     * 
     * @throws SecurityException
     * @throws IllegalArgumentException
     * @throws NoSuchMethodException
     * @throws IllegalAccessException
     * @throws InvocationTargetException
     */
    public MethodReflect(Class<?> i_Class ,String i_MethodURL ,int i_NormType) throws SecurityException, IllegalArgumentException, NoSuchMethodException, IllegalAccessException, InvocationTargetException
    {
        this(i_Class ,i_MethodURL ,false ,i_NormType);
    }
	
	
	
	/**
	 * 方法的反射
	 * 
	 * 可实现xxx.yyy.www(或getXxx.getYyy.setWww)全路径的解释
	 * 可实现xxx.yyy.www(或getXxx.getYyy.getWww)全路径的解释
	 * 
	 * v2.0  2017-06-15  添加:i_MethodURL方法全路径中的每个方法名称,不再区分大小写
	 * 
	 * @param i_Instance    最上层的实例对象实例
	 * @param i_MethodURL   方法全路径
	 * @param i_IsNorm      方法全路径是否符合规范
	 * @param i_NormType    规范类型
	 * 
	 * @throws SecurityException
	 * @throws IllegalArgumentException
	 * @throws NoSuchMethodException
	 * @throws IllegalAccessException
	 * @throws InvocationTargetException
	 */
	public MethodReflect(Object i_Instance ,String i_MethodURL ,boolean i_IsNorm ,int i_NormType) throws SecurityException, IllegalArgumentException, NoSuchMethodException, IllegalAccessException, InvocationTargetException
	{
	    this.classes       = new ArrayList<Class<?>>();
		this.instances     = new ArrayList<Object>();
		this.methods       = new ArrayList<List<MethodInfo>>();
		this.methodsParams = new ArrayList<List<String>>();
		this.methodURL     = i_MethodURL.trim();
		this.methodNames   = this.methodURL.replace("." ,"@").split("@");
		this.isNorm        = i_IsNorm;
		this.normType      = i_NormType;
		
		this.instances.add(i_Instance);
		
		this.parser();
	}
	
	
	
	/**
	 * 方法的反射
	 * 
	 * 可实现getXxx.getYyy.setWww全路径的解释
	 * 可实现getXxx.getYyy.getWww全路径的解释
	 * 
	 * v2.0  2017-06-15  添加:i_MethodURL方法全路径中的每个方法名称,不再区分大小写
	 * 
	 * @param i_Instance    最上层的实例对象实例
	 * @param i_MethodURL   方法全路径
	 * @param i_NormType    规范类型
	 * 
	 * @throws SecurityException
	 * @throws NoSuchMethodException
	 * @throws IllegalArgumentException
	 * @throws IllegalAccessException
	 * @throws InvocationTargetException
	 */
	public MethodReflect(Object i_Instance ,String i_MethodURL ,int i_NormType) throws SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException
	{
		this(i_Instance ,i_MethodURL ,false ,i_NormType);
	}
	
	
	
	/**
	 * 无须反射,只许简单的执行方法就成。
	 * 
	 * 应用于:外界已明确了待执行的方法(通常是getter方法)。
	 * 
	 * 已用在:DBSQL.getSQL(Map)方法。
	 *
	 * @author      ZhengWei(HY)
	 * @createDate  2016-03-18
	 * @version     v1.0
	 *
	 * @param i_Instance
	 * @param i_Method
	 */
	public MethodReflect(Object i_Instance ,Method i_Method)
	{
	    this.instances     = new ArrayList<Object>();
        this.methods       = new ArrayList<List<MethodInfo>>();
        this.methodsParams = new ArrayList<List<String>>();
        this.methodURL     = null;
        this.methodNames   = null;
        this.isNorm        = false;
        this.normType      = $NormType_Getter;
        
        this.instances.add(i_Instance);
        this.methods.add(new ArrayList<MethodInfo>());
        this.methods.get(0).add(new MethodInfo(i_Method));
        this.methodsParams.add(new ArrayList<String>());
	}
	
	
	
	/**
	 * 解释方法全路径
	 * 
	 * 2017-06-15 添加:方法名称不再区分大小写
	 * 2018-05-08 修改:当子类实现父类接口时,方法重载时,可能出现方法名称相同的两个getter方法。
	 *                 方法按修饰符排序后取首个方法,不再向外界抛错。
	 * 
	 * @throws SecurityException
	 * @throws NoSuchMethodException
	 * @throws IllegalArgumentException
	 * @throws IllegalAccessException
	 * @throws InvocationTargetException
	 */
    private void parser() throws SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException
	{
		int v_Index = 0;
		
		
		// 解释出每一层次上的方法的入参参数
		for ( ; v_Index<this.methodNames.length; v_Index++)
		{
		    String [] v_Params = parserMethodParams(this.methodNames[v_Index]);
            
            if ( v_Params != null && v_Params.length >= 1 )
            {
                this.methodNames[v_Index] = parserMethodName(this.methodNames[v_Index]);
                
                List<String> v_ParamList = new ArrayList<String>();
                for (int x=0; x<v_Params.length; x++)
                {
                    if ( !Help.isNull(v_Params[x]) )
                    {
                        v_ParamList.add(v_Params[x].trim());
                    }
                }
                
                this.methodsParams.add(v_ParamList);
            }
            else
            {
                this.methodsParams.add(new ArrayList<String>());
            }
		}
		
		
		if ( this.isNorm )
		{
		    // 最后方法名之前的所有方法,都自动采用Getter形式的补全方法
			for (v_Index = 0; v_Index<this.methodNames.length - 1; v_Index++)
			{
			    if ( this.methodNames[v_Index].startsWith($FixedMethodName) )
			    {
			        this.methodNames[v_Index] = this.methodNames[v_Index].substring(1);
			    }
			    else
			    {
			        this.methodNames[v_Index] = "get" + StringHelp.toUpperCaseByFirst(this.methodNames[v_Index]);
			    }
			}
			
			// 最后一个方法,有可能是Setter方法。
			if ( this.methodNames[v_Index].startsWith($FixedMethodName) )
			{
			    this.methodNames[v_Index] = this.methodNames[v_Index].substring(1);
			}
			else
			{
    			if ( this.normType == $NormType_Setter )
    			{
    				this.methodNames[v_Index] = "set" + StringHelp.toUpperCaseByFirst(this.methodNames[v_Index]);
    			}
    			else
    			{
    				this.methodNames[v_Index] = "get" + StringHelp.toUpperCaseByFirst(this.methodNames[v_Index]);
    			}
			}
		}
		
		
		boolean v_IsClass = !Help.isNull(this.classes);
		
		if ( v_IsClass )
		{
		    for (v_Index = 0; v_Index<this.methodNames.length - 1; v_Index++)
            {
                Class<?>     v_Class   = this.classes.get(v_Index);
                List<Method> v_Methods = getMethodsIgnoreCase(v_Class ,this.methodNames[v_Index] ,this.methodsParams.get(v_Index).size());
                
                if ( Help.isNull(v_Methods) )
                {
                    throw new NullPointerException("Method[" + methodURL + "]'s '" + this.methodNames[v_Index] + "' is not exists.");
                }
                else if ( v_Methods.size() >= 2 )
                {
                    throw new VerifyError("Method[" + methodURL + "]'s '" + this.methodNames[v_Index] + "' is more same Method name.");
                }
                
                if ( this.methodsParams.get(v_Index).size() <= 0 )
                {
                    this.methods.add(MethodInfo.toMethods(v_Methods));
                    this.classes.add(v_Methods.get(0).getReturnType());
                }
                else
                {
                    // 当方法的返回值类型为List集合时,进行二次解释  2017-03-22
                    if ( v_Index >= 1 && MethodReflect.isExtendImplement(this.methods.get(v_Index-1).get(0).toMethod().getReturnType() ,List.class) )
                    {
                        GenericsReturn v_GenericsReturn = MethodReflect.getGenericsReturn(this.methods.get(v_Index-1).get(0).toMethod());
                        
                        if ( v_GenericsReturn.getGenericType() != null )
                        {
                            this.methods.add(MethodInfo.toMethods(v_Methods));
                            this.classes.add(v_GenericsReturn.getGenericType());
                        }     
                    }
                }
            }
		}
		else
		{
		    this.classes.add(this.instances.get(0).getClass());
		    
    		for (v_Index = 0; v_Index<this.methodNames.length - 1; v_Index++)
    		{
    			Class<?>     v_Class         = this.instances.get(v_Index).getClass();
    			List<Method> v_Methods       = getMethodsIgnoreCase(v_Class ,this.methodNames[v_Index] ,this.methodsParams.get(v_Index).size());
    			Object       v_ChildInstance = null;
    			
    			if ( Help.isNull(v_Methods) )
    			{
    			    throw new NullPointerException("Method[" + methodURL + "]'s '" + this.methodNames[v_Index] + "' is not exists.");
    			}
    			else if ( v_Methods.size() >= 2 )
    			{
    			    throw new VerifyError("Method[" + methodURL + "]'s '" + this.methodNames[v_Index] + "' is more same Method name.");
    			}
    			
    			if ( this.methodsParams.get(v_Index).size() <= 0 )
    			{
    			    v_ChildInstance = v_Methods.get(0).invoke(this.instances.get(this.instances.size() - 1));
    			}
    			else
    			{
    			    Object   [] v_ParamObjs  = new Object[this.methodsParams.get(v_Index).size()];
    			    Class<?> [] v_ParamClass = v_Methods.get(0).getParameterTypes(); 
    			    for (int x=0; x<v_ParamClass.length; x++)
    			    {
    			        v_ParamObjs[x] = Help.toObject(v_ParamClass[x] ,this.methodsParams.get(v_Index).get(x));
    			    }
    			    
    			    v_ChildInstance = v_Methods.get(0).invoke(this.instances.get(this.instances.size() - 1) ,v_ParamObjs);
    			}
    			
    			this.methods.add(MethodInfo.toMethods(v_Methods));
    			this.instances.add(v_ChildInstance);
    			this.classes  .add(v_ChildInstance.getClass());
    		}
		}
		
		
		// 解释方法名称的全路径上的最后一个
		Class<?> v_LastClass = null;
		if ( v_IsClass )
		{
		    v_LastClass = this.classes.get(v_Index);
		}
		else
		{
		    v_LastClass = this.instances.get(v_Index).getClass();
		}
		
 		
		if ( this.normType == $NormType_Setter )
		{
		    List<Method> v_Methods = getMethodsIgnoreCase(v_LastClass ,this.methodNames[v_Index] ,1);
		    
		    if ( !Help.isNull(v_Methods) )
		    {
		        this.methods.add(MethodInfo.toMethods(v_Methods));
    		    return;
		    }
		    else
		    {
		        throw new NullPointerException("Method[" + methodURL + "]'s '" + this.methodNames[v_Index] + "' is not exists.");
		    }
		}
		else
		{
		    List<Method> v_Methods = getMethodsIgnoreCase(v_LastClass ,this.methodNames[v_Index] ,this.methodsParams.get(v_Index).size());
			
		    if ( Help.isNull(v_Methods) )
            {
		        // 最后一个Getter方法支持isXXX()方法,支持逻辑方法  2018-03-11
		        if ( this.methodNames[v_Index].startsWith("get") && this.methodNames[v_Index].length() >= 4 )
		        {
		            v_Methods = getMethodsIgnoreCase(v_LastClass ,"is" + this.methodNames[v_Index].substring(3) ,this.methodsParams.get(v_Index).size());
		        }
		        
		        if ( Help.isNull(v_Methods) )
		        {
		            throw new NullPointerException("Method[" + methodURL + "]'s '" + this.methodNames[v_Index] + "' is not exists.");
		        }
            }
            
		    if ( v_Methods.size() >= 2 )
            {
		        // 当子类实现父类接口时,方法重载时,可能出现方法名称相同的两个getter方法
		        // 这里按修饰符降序后,尝试性只保留首个元素,不再将再抛错。 ZhengWei(HY) Add 2018-05-08
		        // throw new VerifyError("Method[" + methodURL + "]'s '" + this.methodNames[v_Index] + "' is more same Method name.");
		        /**
		         * 以下为Method.getModifiers()的基本数值。
                    PUBLIC:        1(二进制  0000 0001)
                    PRIVATE:       2(二进制  0000 0010)
                    PROTECTED:     4(二进制  0000 0100)
                    STATIC:        8(二进制  0000 1000)
                    FINAL:        16(二进制  0001 0000)
                    SYNCHRONIZED: 32(二进制  0010 0000)
                    VOLATILE:     64(二进制  0100 0000)
                    TRANSIENT:   128(二进制  1000 0000)
                    NATIVE:      256(二进制  0001 0000 0000)
                    INTERFACE:   512(二进制  0010 0000 0000)
                    ABSTRACT:   1024(二进制  0100 0000 0000)
                    STRICT:     2048(二进制  1000 0000 0000)
		         */
		        Help.toSort(v_Methods ,"modifiers");
		        for (int i=v_Methods.size()-1; i>=1; i--)
		        {
		            v_Methods.remove(i);
		        }
		        this.methods.add(MethodInfo.toMethods(v_Methods));
            }
            else
            {
                this.methods.add(MethodInfo.toMethods(v_Methods));
            }
		}
	}
	
	
	
	/**
	 * 方法全路径的赋值(Setter)
	 * 
	 * 支持 Setter 方法的多个重载
	 * 
	 * @param i_ParamValue  方法的入参参数
	 * 
	 * @throws IllegalArgumentException
	 * @throws IllegalAccessException
	 * @throws InvocationTargetException
	 */
	public void invoke(Object i_ParamValue) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException
	{
		int v_Index = this.instances.size() - 1;
		
		if ( this.normType == $NormType_Setter )
		{
		    if ( !Help.isNull(this.methods) )
		    {
    			List<MethodInfo> v_Methods = this.methods.get(v_Index);
    			for (int i=0; i<v_Methods.size(); i++)
    		    {
    			    if ( isExtendImplement(i_ParamValue ,v_Methods.get(i).getParameterTypes()[0]) )
    			    {
    			        v_Methods.get(i).toMethod().invoke(this.instances.get(v_Index) ,i_ParamValue);
    			        return;
    			    }
    		    }
		    }
		}
	}
	
	
	
	/**
	 * 方法全路径的返回值类型
	 * 
	 * @author      ZhengWei(HY)
	 * @createDate  2015-12-10
	 * @version     v1.0
	 *
	 * @return
	 */
    public Class<?> getReturnType() 
    {
        if ( this.normType == $NormType_Setter )
        {
            return null;
        }
        
        boolean v_IsClass = !Help.isNull(this.classes);
        int     v_Index   = 0;
        
        if ( v_IsClass )
        {
            v_Index = this.classes.size() - 1;
            
            return this.methods.get(v_Index).get(0).toMethod().getReturnType();
        }
        else
        {
            v_Index = this.instances.size() - 1;
            
            return this.methods.get(v_Index).get(0).toMethod().getReturnType();
        }
    }
    
    
    
    /**
     * 方法全路径的返回值的方法对象(最后一个方法)
     * 
     * @author      ZhengWei(HY)
     * @createDate  2017-03-27
     * @version     v1.0
     *
     * @return
     */
    public Method getReturnMethod() 
    {
        if ( this.normType == $NormType_Setter )
        {
            return null;
        }
        
        boolean v_IsClass = !Help.isNull(this.classes);
        int     v_Index   = 0;
        
        if ( v_IsClass )
        {
            v_Index = this.classes.size() - 1;
            
            return this.methods.get(v_Index).get(0).toMethod();
        }
        else
        {
            v_Index = this.instances.size() - 1;
            
            return this.methods.get(v_Index).get(0).toMethod();
        }
    }
    
    
    
	/**
	 * 方法全路径的获取值(Getter)
	 * 
	 * @throws IllegalArgumentException
	 * @throws IllegalAccessException
	 * @throws InvocationTargetException
	 */
	public Object invoke() throws IllegalArgumentException, IllegalAccessException, InvocationTargetException
	{
		int v_Index = this.instances.size() - 1;
		
		if ( this.normType == $NormType_Setter )
		{
			return null;
		}
		else
		{
		    Method v_Method = this.methods.get(v_Index).get(0).toMethod();
		    
		    if ( this.methodsParams.get(v_Index).size() <= 0 )
            {
                return v_Method.invoke(this.instances.get(v_Index));
            }
            else
            {
                Object   [] v_ParamObjs  = new Object[this.methodsParams.get(v_Index).size()];
                Class<?> [] v_ParamClass = v_Method.getParameterTypes(); 
                for (int x=0; x<v_ParamClass.length; x++)
                {
                    v_ParamObjs[x] = Help.toObject(v_ParamClass[x] ,this.methodsParams.get(v_Index).get(x));
                }
                
                return v_Method.invoke(this.instances.get(v_Index) ,v_ParamObjs);
            }
		}
	}
	
	
	
	/**
	 * 方法全路径的获取值(Getter)
	 * 
	 * @author      ZhengWei(HY)
	 * @createDate  2017-03-17
	 * @version     v1.0
	 *
	 * @param i_Instance  实例对象
	 * @return
	 * @throws IllegalArgumentException
	 * @throws IllegalAccessException
	 * @throws InvocationTargetException
	 */
    public Object invokeForInstance(Object i_Instance) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException
    {
        if ( this.normType == $NormType_Setter )
        {
            return null;
        }
        else
        {
            Object v_Instance = i_Instance;
            for (int v_Index=0; v_Index<this.methods.size(); v_Index++)
            {
                Method v_Method = this.methods.get(v_Index).get(0).toMethod();
                
                if ( v_Instance == null ){ break; }
                
                if ( this.methodsParams.get(v_Index).size() <= 0 )
                {
                    v_Instance = v_Method.invoke(v_Instance);
                }
                else
                {
                    Object   [] v_ParamObjs  = new Object[this.methodsParams.get(v_Index).size()];
                    Class<?> [] v_ParamClass = v_Method.getParameterTypes(); 
                    for (int x=0; x<v_ParamClass.length; x++)
                    {
                        v_ParamObjs[x] = Help.toObject(v_ParamClass[x] ,this.methodsParams.get(v_Index).get(x));
                    }
                    
                    v_Instance = v_Method.invoke(v_Instance ,v_ParamObjs);
                }
            }
            
            return v_Instance;
        }
    }
    
    
    
    /**
     * 方法全路径的获取值(Getter)
     * 
     * @author      ZhengWei(HY)
     * @createDate  2017-03-22
     * @version     v1.0
     *
     * @param i_Instance  实例对象
     * @param i_Params    执行参数。
     *                    Map.key   为 xxx.yyy(Index).www 格式中的 Index 参数名称
     *                    Map.value 为参数的值
     * @return
     * @throws IllegalArgumentException
     * @throws IllegalAccessException
     * @throws InvocationTargetException
     */
    public Object invokeForInstance(Object i_Instance ,Map<String ,Object> i_Params) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException
    {
        if ( this.normType == $NormType_Setter )
        {
            return null;
        }
        else
        {
            Object v_Instance = i_Instance;
            for (int v_Index=0; v_Index<this.methods.size(); v_Index++)
            {
                Method v_Method = this.methods.get(v_Index).get(0).toMethod();
                
                if ( v_Instance == null ){ break; }
                
                if ( this.methodsParams.get(v_Index).size() <= 0 )
                {
                    v_Instance = v_Method.invoke(v_Instance);
                }
                else
                {
                    int       v_ParamSize = this.methodsParams.get(v_Index).size();
                    Object [] v_ParamObjs = new Object[v_ParamSize];
                    for (int x=0; x<v_ParamSize; x++)
                    {
                        v_ParamObjs[x] = i_Params.get(this.methodsParams.get(v_Index).get(x));
                    }
                    
                    v_Instance = v_Method.invoke(v_Instance ,v_ParamObjs);
                }
            }
            
            return v_Instance;
        }
    }
    
    
    
    /**
     * 方法全路径的填充值(Setter)
     * 
     * @author      ZhengWei(HY)
     * @createDate  2017-05-08
     * @version     v1.0
     *
     * @param i_Instance  实例对象
     * @param i_Value     Setter方法的入参数值
     * @throws IllegalArgumentException
     * @throws IllegalAccessException
     * @throws InvocationTargetException
     * @throws InstantiationException 
     */
    public void invokeSetForInstance(Object i_Instance ,Object i_Value) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException, InstantiationException
    {
        if ( this.normType == $NormType_Getter )
        {
            return;
        }
        else
        {
            Object v_Instance    = i_Instance;
            Object v_InstanceOld = null;
            int    v_Index       = 0;
                    
            for (; v_Index<this.methods.size()-1; v_Index++)
            {
                Method v_Method = this.methods.get(v_Index).get(0).toMethod();
                
                if ( v_Instance == null ){ break; }
                
                v_InstanceOld = v_Instance;
                        
                if ( this.methodsParams.get(v_Index).size() <= 0 )
                {
                    v_Instance = v_Method.invoke(v_Instance);
                }
                else
                {
                    Object   [] v_ParamObjs  = new Object[this.methodsParams.get(v_Index).size()];
                    Class<?> [] v_ParamClass = v_Method.getParameterTypes(); 
                    for (int x=0; x<v_ParamClass.length; x++)
                    {
                        v_ParamObjs[x] = Help.toObject(v_ParamClass[x] ,this.methodsParams.get(v_Index).get(x));
                    }
                    
                    v_Instance = v_Method.invoke(v_Instance ,v_ParamObjs);
                }
                
                if ( null == v_Instance )
                {
                    String v_MethodName = v_Method.getName();
                    
                    if ( v_MethodName.startsWith("is") )
                    {
                        v_MethodName = v_MethodName.substring(2);
                    }
                    else if ( v_MethodName.startsWith("get") )
                    {
                        v_MethodName = v_MethodName.substring(3);
                    }
                    
                    Method v_SetMethod = MethodReflect.getSetMethod(v_InstanceOld.getClass() ,v_MethodName ,true);
                    
                    if ( null != v_SetMethod )
                    {
                        v_Instance = v_Method.getReturnType().newInstance();
                        v_SetMethod.invoke(v_InstanceOld ,v_Instance);
                    }
                    else
                    {
                        throw new NullPointerException("Method[" + v_Method.getName() + "] return is null.");
                    }
                }
            }
            
            if ( v_Instance == null ){ return; }
            
            Method v_Method = this.methods.get(v_Index).get(0).toMethod();
            
            if ( MethodReflect.isExtendImplement(v_Method.getParameterTypes()[0] ,i_Value.getClass()) )
            {
                v_Method.invoke(v_Instance ,i_Value);
            }
            else
            {
                v_Method.invoke(v_Instance ,Help.toObject(v_Method.getParameterTypes()[0] ,i_Value.toString()));
            }
        }
    }
    
	
	
	public String getMethodURL()
	{
		return methodURL;
	}



    /*
    ZhengWei(HY) Del 2016-07-30
    不能实现这个方法。首先JDK中的Hashtable、ArrayList中也没有实现此方法。
    它会在元素还有用,但集合对象本身没有用时,释放元素对象
    
    一些与finalize相关的方法,由于一些致命的缺陷,已经被废弃了
	protected void finalize() throws Throwable 
	{
		this.instances.clear();
		this.methods.clear();
		
		super.finalize();
	}
	*/
	
}





/**
 * 向数据库表插入数据时,通过Java生成主键的功能。与SQL占位符配合使用。
 *
 * @author      ZhengWei(HY)
 * @createDate  2016-03-18
 * @version     v1.0
 */
class MethodReflectUUID
{
    
    private static MethodReflectUUID $MRUUID;
    
    
    
    public synchronized static MethodReflectUUID getInstance()
    {
        if ( $MRUUID == null )
        {
            $MRUUID = new MethodReflectUUID();
        }
        return $MRUUID;
    }
    
    
    
    private MethodReflectUUID()
    {
        
    }
    
    
    
    /**
     * 获取UUID。全部大写,并且去除"-"字符的东东
     * 
     * @return
     */
    public String getUUID()
    {
        return StringHelp.getUUID();
    }
    
}