Probably a more flexible approach is to check all the constructors and search for a compatible type:
public static <T> T getNewInstance(final Class<T> clazz, Object... constructorParameters) throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { Constructor<?> candidate = null; for(Constructor<?> constructor : clazz.getConstructors()) { if(Modifier.isPublic(constructor.getModifiers()) && isConstructorCompatible(constructor, constructorParameters)) { if(candidate == null) candidate = constructor; else throw new IllegalArgumentException("Several constructors found which are compatible with given arguments"); } } if(candidate == null) throw new IllegalArgumentException("No constructor found which is compatible with given arguments"); return (T) candidate.newInstance(constructorParameters); } private static boolean isConstructorCompatible(Constructor<?> constructor, Object[] constructorParameters) { Class<?>[] parameterTypes = constructor.getParameterTypes(); if(parameterTypes.length != constructorParameters.length) return false; for(int i=0; i<parameterTypes.length; i++) if(!isParameterCompatible(parameterTypes[i], constructorParameters[i])) return false; return true; } private static boolean isParameterCompatible(Class<?> type, Object parameter) { if(parameter == null) return !type.isPrimitive(); if(type.isInstance(parameter)) return true; if(type.isPrimitive()) { if (type == int.class && parameter instanceof Integer || type == char.class && parameter instanceof Character || type == byte.class && parameter instanceof Byte || type == short.class && parameter instanceof Short || type == long.class && parameter instanceof Long || type == float.class && parameter instanceof Float || type == double.class && parameter instanceof Double || type == boolean.class && parameter instanceof Boolean) return true; } return false; }
There are still open issues, such as varargs-constructors. Also, cases of ambiguity will not be resolved, as javac did (for example, if you have the constructor MyObj(Object) and MyObj(String) , you cannot use the latter, both are the same).
source share