0

Assuming I have an object and I took it fields:

Field[] fields = obj.getFields();

Now I'm iterating through each one and would like to print their members if it's some kind of class, otherwise just use field.get(obj) in case it's a string, int or anything that this command will print its value, not just the reference pointer.

How can I detect it?

Duncan Jones
  • 67,400
  • 29
  • 193
  • 254
buddy123
  • 5,679
  • 10
  • 47
  • 73
  • Every `System.out.println(obj)` call will implicitly invoke `System.out.println(obj.toString())`. So int, strings and any other class that overrides the `toString()` method will not print the reference pointer. – BackSlash Dec 19 '14 at 08:44
  • OK, but is there a way to tell if its a class declared in the project and not internally java one? – buddy123 Dec 19 '14 at 08:46
  • @e-r-a-n You can check the package name. But that doesn't solve the problem of knowing whether `toString()` was overriden or not. Is this your ultimate goal? If so, see [Detect if object has overriden toString()](http://stackoverflow.com/q/22866925). – Duncan Jones Dec 19 '14 at 08:46
  • @Duncan no, sadly no. I would like to go over class fields and print their values. but if its some kind of class I created, I want to do the entire process of printing fields on it as well – buddy123 Dec 19 '14 at 08:51

5 Answers5

1

You can get, without instantiation required, the Type of each field of a class like this:

public class GetFieldType {

    public static void main (String [] args) {
        Field [] fields = Hello.class.getFields();

        for (Field field: fields) {
            System.out.println(field.getGenericType());
        }
    }

    public static class Hello {
        public ByeBye bye;
        public String message;
        public Integer b;
        ...
    }
}
Ian2thedv
  • 2,691
  • 2
  • 26
  • 47
0

You can use instanceof to tell the objects apart.

public static void main(String[] args) throws FileNotFoundException, UnsupportedEncodingException {
    Object[] objects = new Object[4];
    objects[0] = new Integer(2);
    objects[1] = "StringTest";
    objects[2] = new BigDecimal(2.00d);
    for (Object obj : objects) {
        if (obj != null) {
            if (obj instanceof BigDecimal) {
                System.out.println("bigdecimal found " + obj);
            } else if (obj instanceof String) {
                System.out.println("String found " + obj);
            } else {
                System.out.println("Integer found " + obj);
            }
        }
        else{
            System.out.println("object is null");
        }
    }
}
MihaiC
  • 1,618
  • 1
  • 10
  • 14
0

If you need to test if an object is from your project, you can look at the package name and compare it to your project's package name.

You can either do this on the declared type of the field or on the runtime type of the field contents. The snippet below demonstrates the latter approach:

SomeClass foo = new SomeClass();

for (Field f : foo.getClass().getDeclaredFields()) {

  boolean wasAccessible = f.isAccessible();
  try {
    f.setAccessible(true);
    Object object = f.get(foo);

    if (object != null) {

      if (object.getClass().getPackage().getName()
          .startsWith("your.project.package")) {
        // one of yours
      }
    } else {
      // handle a null value
    }
  } finally {
    f.setAccessible(wasAccessible);
  }
}

Do remember that obj.getFields(); only returns publicly-accessible fields. You may want to consider getDeclaredFields() as I've done above. If you stick with getFields(), you can omit the accessibility code in the above example.

Duncan Jones
  • 67,400
  • 29
  • 193
  • 254
0

With a bit of work, you could distinguish your classes by the classloader that loaded them. Take a look at this:

Find where java class is loaded from

Though this could help, it's not going to be the silver bullet for your problem, mainly because:

  • primitives (byte, short, char, int, long, float, double, and boolean) are not classes.
  • the architecture of classloaders is different in different app servers.
  • the same class could be loaded many times by different classloaders.
Community
  • 1
  • 1
Andres
  • 10,561
  • 4
  • 45
  • 63
0

what I understood is you what to go recursive in object hierarchy and get values of primitives

public class ParentMostClass {
   int a = 5;
   OtherClass other = new OtherClass();

   public static void main(String[] args) throws IllegalArgumentException,
    IllegalAccessException {
      ParentMostClass ref = new ParentMostClass();
      printFiledValues(ref);
  }

public static void printFiledValues(Object obj)
    throws IllegalArgumentException, IllegalAccessException {

    Class<? extends Object> calzz = obj.getClass();
    Field[] fileds = obj.getClass().getDeclaredFields();

    for (Field field : fileds) {
        Object member = field.get(obj);
        // you need to handle all primitive, they are few
        if (member instanceof String || member instanceof Number) {
            System.out.println(calzz + "->" + field.getName() + " : "
            + member);
        } else {
           printFiledValues(member);
    }
  }
}
}

public class OtherClass {
    int b=10;
}

I got output as

class com.example.ParentMostClass->a : 5
class com.example.OtherClass->b : 10
Sandy
  • 142
  • 8