Wahrscheinlich flexibleren Ansatz ist es, alle Konstrukteure zu überprüfen und die kompatibles wie diese finden:
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;
}
Es gibt noch offene Fragen, obwohl wie varargs-Konstrukteuren. Auch Mehrdeutigkeitsfälle werden nicht wie bei javac gelöst (wenn Sie zum Beispiel MyObj(Object)
und Konstruktor haben, können Sie den letzteren nicht verwenden).
Sie müssen das Array von Konstruktoren für den Konstruktor suchen, dessen Parameter mit den Argumenten übereinstimmen. –
Woher kommt 'AbstractClass'? Warum wird es benötigt? –
Und Ihre Methodensignatur sollte so etwas wie 'public T getNewInstance sein (letzte Klasse clazz, Object ... cs);' –
Codebender