How to invoke method on all fields using Reflection?
How to invoke method on all fields? using Reflection?
class MyField
{
publicvoid runNow();
publicvoid setValue(int value);
}
class Struct1
{
public MyField myFieldA;
public MyField myFieldB;
//... a lot more
}
abstractclass AbstractStruct
{
publicvoid runAllFields()
{
Field fields[] = this.getClass().getFields();
for (Field field: fields)
{
Class c = field.getDeclaringClass();
Method m = c.getMethod("runNow",new Class[]{});
// Q: How do I invoke this method? What is "XXX"?
m.invoke(XXX,new Object[]{});
}
}
}
What are the alternatives?
1.) Put all fields into a Collection? It will be easy to setup a loop to invoke .runNow() on each MyField, but I will lose the easy: struct1.myField1.setValue(123);
2.) Make invokeAllMyFields() abstract, and make all .runNow() calls myself in every Struct, but it can be error prone when there are a lot of fields.
3.) AspectJ?
Thank you!
[2070 byte] By [
fanbanlo2a] at [2007-11-26 14:10:21]

> What do you mean by "business need"?
That means that either there is a direct business requirement or indirectly a business requirement that has lead to this design decision.
> What should XXX be in the code sample on the first
> post?
>
A very quick cursory glance at the javadocs turns up the following method.
Field.setInt()
> What should XXX be in the code sample on the first
> post?
>
>
> A very quick cursory glance at the javadocs turns up
> the following method.
>
> Field.setInt()
That's not what XXX needs, XXX is the first pram of Invoke(), the Instance of the object, yet I'm not sure how to get it from the code sample above.
Any help would be appricated, thank you.
>
> That's not what XXX needs, XXX is the first pram of
> Invoke(), the Instance of the object, yet I'm not
> sure how to get it from the code sample above.
Ok.
Conceptually which of the following do you want to do?
1. runNow(myFieldA); runNow(myFieldB);
2. runNow(myFieldA, myFieldB);
3. myFieldA.runNow(); myFieldB.runNow();
To give an example:
I have used a code like this e.g. to debug data object's fields
(because I was not happy with the way the usual toString() prints fields).
This method prints all fields that have a method getXXX() or isXXX()
and includeToString() says that the field value should be printed:
public String toString() {
StringBuffer out = new StringBuffer();
if (logger.isDebugEnabled()) {
Class c = getClass();
Method m[] = c.getMethods();
for (int i = 0; i < m.length; i++) {
String methodName = m[i].getName();
if (includeToString(methodName) && (methodName.startsWith("get") || methodName.startsWith("is"))) {
try {
Object o = m[i].invoke(this, (Object[]) null);
String result = "null";
if (o != null) {
result = o.toString();
}
String columnName;
if (methodName.startsWith("get")) {
columnName = methodName.substring(3);
} else {
columnName = methodName.substring(2);
}
out.append(columnName).append(" = ").append(result).append('\n');
} catch (Exception e) {
out.append("FAILED: ").append(methodName).append('\n');
}
}
}
} else {
out.append(c.getName());
}
return (out.toString());
}