buddy123
buddy123

Reputation: 6327

Determine if a field is a type I created, using reflection

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?

Upvotes: 0

Views: 831

Answers (5)

Ian2thedv
Ian2thedv

Reputation: 2701

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;
        ...
    }
}

Upvotes: 1

Sandy
Sandy

Reputation: 152

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

Upvotes: 0

Andres
Andres

Reputation: 10727

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.

Upvotes: 0

Duncan Jones
Duncan Jones

Reputation: 69399

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.

Upvotes: 0

MihaiC
MihaiC

Reputation: 1583

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");
        }
    }
}

Upvotes: 0

Related Questions