class ClassUtils {

    public static <T> T newInstanceWithArgs(Class<T> clazz, Class<?>[] argTypes, Object[] args)
        throws SofaRpcRuntimeException {
        if (CommonUtils.isEmpty(argTypes)) {
            return newInstance(clazz);
        }
        try {
            if (!(clazz.isMemberClass() && !Modifier.isStatic(clazz.getModifiers()))) {
                Constructor<T> constructor = clazz.getDeclaredConstructor(argTypes);
                constructor.setAccessible(true);
                return constructor.newInstance(args);
            } else {
                Constructor<T>[] constructors = (Constructor<T>[]) clazz.getDeclaredConstructors();
                if (constructors == null || constructors.length == 0) {
                    throw new SofaRpcRuntimeException("The " + clazz.getCanonicalName()
                        + " has no constructor with argTypes :" + Arrays.toString(argTypes));
                }
                Constructor<T> constructor = null;
                for (Constructor<T> c : constructors) {
                    Class[] ps = c.getParameterTypes();
                    if (ps.length == argTypes.length + 1) { // 长度多一
                        boolean allMath = true;
                        for (int i = 1; i < ps.length; i++) { // 而且第二个开始的参数类型匹配
                            if (ps[i] != argTypes[i - 1]) {
                                allMath = false;
                                break;
                            }
                        }
                        if (allMath) {
                            constructor = c;
                            break;
                        }
                    }
                }
                if (constructor == null) {
                    throw new SofaRpcRuntimeException("The " + clazz.getCanonicalName()
                        + " has no constructor with argTypes :" + Arrays.toString(argTypes));
                } else {
                    constructor.setAccessible(true);
                    Object[] newArgs = new Object[args.length + 1];
                    System.arraycopy(args, 0, newArgs, 1, args.length);
                    return constructor.newInstance(newArgs);
                }
            }
        } catch (SofaRpcRuntimeException e) {
            throw e;
        } catch (Throwable e) {
            throw new SofaRpcRuntimeException(e.getMessage(), e);
        }
    }

}