views:

1343

answers:

4

I have a class with numerous parameters of various types. I want to iterate over all type A members , and run a specific functions ( A.doSomething() )

This doesn't even compile: The conversion from field to XPathDataElement is illegal

Field[] fields = this.getClass().getDeclaredFields();
  for (Field field : fields) {
     if (field. getType().getName().equals(XPathDataElement.class.getName()))
        {    
       tmp = (XPathDataElement)field; // Doesn't compile
       sb.append(field.getName() + ":"); 
       tmp.update();
     }
    }

Thanks!

A: 

You don't seem to assign anything to the obj that you cast to XPathDataElement in the loop.

You probably want to do something like this:

tmp = (XPathDataElement)field.get(this);
andri
+2  A: 

I strongly suggest avoiding reflection unless you really need it.

Just write the code out:

this.x.doSomething();
this.y.doSomething();
this.z.doSomething();

Or if you like:

for (A a : new A[] {
    this.x, this.y, this.z
}) {
    a.doSomething();
}
Tom Hawtin - tackline
Would you care to elaborate why I shouldn't use reflection? thanks!
yossale
you lose compile time safety, it will be a bit slower, generally you should use interfaces over reflection to ensure that things are there. Compile time safety is one of the big pluses in Java (for some it is also one of the downsides). Can you elaborate more on why you want to use reflection?
TofuBeer
What TofuBear said, plus: It's more code and code which is easier to get wrong and difficult to follow. Reflection and (mobile code) security don't mix very well either.
Tom Hawtin - tackline
+7  A: 

It's hard to debug your code when you don't say what's wrong with it.

Two things I can see:

  1. There's no need to compare strings to decide if the field's type is the right class.

    if (field.getType().equals(XPathDataElement.class))
    

    should work.

    Edit: Steve Reed points out that you don't necessarily need it to be exactly XPathDataElement; a subclass will work just as well. To check if the field can be treated as an XPathDataElement, you should use Class.isAssignableFrom(Class).

    if (XPathDataElement.class.isAssignableFrom(field.getType()))
    

    would be the code.

  2. I guess your real question is how to get the value of a field reflectively? If so, then Field.get(Object) is what you want. The object that you pass to get() is the one whose field you want to retrieve; if you're operating on this (which is a strong code smell), then your code would be

    XPathDataElement tmp = (XPathDataElement) field.get(this);
    
Michael Myers
You're absolutely right about your first comment , I've edited the post. thanks!
yossale
+1  A: 

A couple of pointers:

  1. Compare the classes for equality, not their names.

    field.getType().equals(XPathDataElement.class)

  2. Or better yet, use isAssignableFrom(java.lang.Class) to handle the case where the class declares a return type as a sublclass of what you're looking for

    XPathDataElement.class.isAssignableFrom(field.getType())

  3. You're iterating over fields, not method. Your question leads me to assume you want the latter, and if so, use:

    this.getClass().getDeclaredMethods()

Steve Reed