Here is some code I've been twiddling with to try and lazily fill in fields in object, mostly for object factories in JUnit but it could be quite a useful method to have.
private void lazyObjectFill(Object profil) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
final Method[] list = profil.getClass().getDeclaredMethods();
for (Method m : list) {
if (Modifier.isPublic(m.getModifiers()) && m.getName().startsWith("set")) {
final Class< ?>[] parameterTypes = m.getParameterTypes();
if (parameterTypes.length == 1) {
final Class< ?> clazz = parameterTypes[0];
if (clazz == String.class) {
log.info("Invoking " + m.getName() + " with [\"\"]");
m.invoke("");
} else if (clazz.isPrimitive() && Defaults.defaultValue(clazz) != null) {
log.info("Invoking " + m.getName() + " with [" + Defaults.defaultValue(clazz) + "]");
m.invoke(Defaults.defaultValue(clazz));
}
}
}
}
}
We get the following exception when running this code on an object.
java.lang.IllegalArgumentException: object is not an instance of declaring class
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:592)
The exception occurs when running m.invoke(""); on a string setter.
Updated source code for the benefit of the googlers.
private void lazyObjectFill(Object obj) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
final Method[] list = obj.getClass().getDeclaredMethods();
for (Method method : list) {
method.setAccessible(true);
if (Modifier.isPublic(method.getModifiers()) && method.getName().startsWith("set")) {
final Class< ?>[] parameterTypes = method.getParameterTypes();
if (parameterTypes.length == 1) {
final Class< ?> clazz = parameterTypes[0];
if (clazz == String.class) {
log.info("Invoking " + method.getName() + " with [\"\"]");
method.invoke(obj, "");
} else if (clazz.isPrimitive() && Defaults.defaultValue(clazz) != null) {
log.info("Invoking " + method.getName() + " with [" + Defaults.defaultValue(clazz) + "]");
method.invoke(obj, Defaults.defaultValue(clazz));
}
}
}
}
}