Link to home
Start Free TrialLog in
Avatar of seanfurlong
seanfurlong

asked on

Traverse Members of a java class

Is it possible to generically traverse through a list members in  a class and store their values in a string

eg

Class test
{
         String  a = " hello ";
         String  b = "world ";
}

The solution would be a function called test.writemem which would traverse through the members and return "Hello world"  without calling the members by name.(saying String = a + b;)

ASKER CERTIFIED SOLUTION
Avatar of armoghan
armoghan
Flag of Pakistan image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of Mick Barry
Use reflection

Class c = test.class;
Field[] fileds = c.getDeclaredFields();

the order is indeterminate though.
public class Test2 {
  public static void main(String args[])
    throws Exception {
    Field f;
   
    f = test .class.getField("a");
    System.out.println("" + f);

    f = test .class.getField("b");
    System.out.println(""+ f);
  }
}
This piece of code works

final Field fields[] =
   final Field fields[] =     test .class.getDeclaredFields();
    for (int i = 0; i < fields.length; ++i) {
   
        test fieldTest = new test ();
        Field f = fields[i];
        f.setAccessible(true);
        try {
          System.out.println(f.get(fieldTest));
        }
        catch (IllegalAccessException ex) {
        }
        catch (IllegalArgumentException ex) {
        }
    }
Avatar of Emilda
Emilda

Try this:

import java.lang.reflect.Field;

public class TestFields {
   String  a = " hello ";
   String  b = "world ";

  public static void main(String[] args) {
    TestFields test = new TestFields();
    try {
           String values = test.writemem();              
           System.out.println(values);
    } catch (IllegalAccessException e) {
    }
  }
  public String writemem() throws IllegalAccessException {
    Field[] fields = TestFields.class.getDeclaredFields();
    String values = new String();
          
    for(int i=0; i<fields.length; i++) {                
          String name =  fields[i].getName();
          if(name.indexOf("class") == -1) {
             String value = fields[i].get(this).toString();
             values = values + value;
          }                
    }
    return values;
  }
}

This program will print the fields as u have asked. Output of the following programs on console is "hello world  under world"

package untitled1;

import java.lang.reflect.*;
import java.awt.*;

public class Untitled1 {
  public String a = "hello";
  public String b = "world";
  public String c = " under world";
  public Untitled1() {
  }

  public static void main(String[] args) {
    Untitled1 u = new Untitled1();
    Rectangle r = new Rectangle(100, 325);
    u.me(u.getClass());
  }

  void me(Class c) {
    Field heightField;
    Field field;
    Integer heightValue;
    StringBuffer buf = new StringBuffer();
    try {
      Field[] publicFields = c.getFields();
      for (int i = 0; i < publicFields.length; i++) {
        field = publicFields[i];
        String fieldName = publicFields[i].getName();
        String value = (String) field.get(this);
        buf.append(value);
        buf.append(" ");
      }
    }
    catch (SecurityException e) {
      System.out.println(e);
    }
    catch (IllegalAccessException e) {
      System.out.println(e);
    }
    System.out.println(buf.toString());

  }

}
getFields() returns only the public fields.
The requiremnt is not to list private fields.
See the class given in the question. The fields given inside that doesn't have the public identifier.
Here is the modified code: this will print all variables, public, private, and package level in a class.


package untitled1;

import java.lang.reflect.*;
import java.awt.*;

public class Untitled1 {
  public String a = "hello";
  public String b = "world";
  private String c = " under world";
  public Untitled1() {
  }

  public static void main(String[] args) {
    Untitled1 u = new Untitled1();
    Rectangle r = new Rectangle(100, 325);
    u.me(u.getClass());
  }

  void me(Class c) {
    Field heightField;
    Field field;
    Integer heightValue;
    StringBuffer buf = new StringBuffer();
    try {
      Field[] publicFields = c.getDeclaredFields();
      for (int i = 0; i < publicFields.length; i++) {
        field = publicFields[i];
        String fieldName = publicFields[i].getName();
        String value = (String) field.get(this);
        buf.append(value);
        buf.append(" ");
      }
    }
    catch (SecurityException e) {
      System.out.println(e);
    }
    catch (IllegalAccessException e) {
      System.out.println(e);
    }
    System.out.println(buf.toString());

  }

}
The last code posted by me will print this our put.

hello world  under world

U can verify this.
Dear seanfurlong, COnfirm me that the code pasted by me is working or not. I have tested and it is printing all the members of the class i.e. private, public and package level with their values.
thanx :)