Muhtemelen daha esnek bir yaklaşım bu gibi uyumlu bir bütün kurucular kontrol edip bulmaktır:
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;
}
varargs-yapıcıları gibi olsa açık konular hala vardır. Ayrıca belirsizlik durumları javac tarafından yapıldığı gibi çözülmeyecektir (örneğin, MyObj(Object)
ve MyObj(String)
yapıcınız varsa, ikincisinin her ikisini de kullanamazsınız).
Parametreleri argümanlarla eşleşen yapıcı için yapıcı dizisini aramak zorundasınız. –
'AbstractClass' nerede ortaya çıkıyor? Neden ihtiyaç duyuluyor? –
Ve yöntem imzanız 'public T getNewInstance (final Sınıfı clazz, Object ... cs);' –
Codebender