1

I am working on this program which would print all the information related to an object, that information includes:

For each slice (class in the object hierarchy) in x:

  • Print the class name of the slice.

  • For each non-static field in that slice:

    • Print all the field modifiers followed by the field name.
    • Print the value of the field as follows:
      • If the field is null print null.
      • If the field is a primitive type print its value
      • If the field is a String print its value
      • If the field is an array:
        • Loop over the elements in the array
        • Print the index
        • Recursively print the details of the array item
      • Otherwise, recursively print the details of the field

I have pretty much printed all the information using the code below:

public void print(Object obj) { Class cl = obj.getClass(); while(cl != null) { System.out.println("Class Name: " + cl.getName()); Field[] fields = cl.getFields(); System.out.println("FIELDS: "); for(int i=0; i<fields.length; i++) { String modifier = Modifier.toString(fields[i].getModifiers()); String name = fields[i].getName(); System.out.print("Modifier: "+modifier+" Name: "+name+ " "); try { if(fields[i].get(cl) == null) System.out.print("Value: NULL"); } catch ( IllegalArgumentException | IllegalAccessException ex) { Logger.getLogger(JCP.class.getName()).log(Level.SEVERE, null, ex); } if(fields[i].getType().isPrimitive()) try { System.out.println("Value: " + fields[i].get(cl)); } catch ( IllegalArgumentException | IllegalAccessException ex) { Logger.getLogger(JCP.class.getName()).log(Level.SEVERE, null, ex); } if(fields[i].getType().isArray()) { try { Object[] object=(Object[])fields[i].get(obj); System.out.print("Values: "); for(int j=0;j<object.length;j++){ System.out.print(object[j].toString() + ","); } } catch ( IllegalArgumentException | IllegalAccessException ex) { Logger.getLogger(JCP.class.getName()).log(Level.SEVERE, null, ex); } } } System.out.println(); cl = cl.getSuperclass(); } } 

On testing this on the following class:

public class hello { private int privateField1; private long privateField2; public int publicField1; public int publicField2; public hello() { } } 

I got the following output:

Class Name: hello FIELDS: Mar 10, 2014 2:54:36 PM JCP print SEVERE: null java.lang.IllegalArgumentException: Can not set int field hello.publicField1 to java.lang.Class at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:164) Modifier: public Name: publicField1 Modifier: public Name: publicField2 Class Name: java.lang.Object FIELDS: at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:168) at sun.reflect.UnsafeFieldAccessorImpl.ensureObj(UnsafeFieldAccessorImpl.java:55) at sun.reflect.UnsafeIntegerFieldAccessorImpl.getInt(UnsafeIntegerFieldAccessorImpl.java:56) at sun.reflect.UnsafeIntegerFieldAccessorImpl.get(UnsafeIntegerFieldAccessorImpl.java:36) at java.lang.reflect.Field.get(Field.java:379) at JCP.print(JCP.java:211) at JCP.start(JCP.java:36) at Main.main(Main.java:11) Mar 10, 2014 2:54:36 PM JCP print SEVERE: null java.lang.IllegalArgumentException: Can not set int field hello.publicField1 to java.lang.Class at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:164) at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:168) at sun.reflect.UnsafeFieldAccessorImpl.ensureObj(UnsafeFieldAccessorImpl.java:55) at sun.reflect.UnsafeIntegerFieldAccessorImpl.getInt(UnsafeIntegerFieldAccessorImpl.java:56) at sun.reflect.UnsafeIntegerFieldAccessorImpl.get(UnsafeIntegerFieldAccessorImpl.java:36) at java.lang.reflect.Field.get(Field.java:379) at JCP.print(JCP.java:219) at JCP.start(JCP.java:36) at Main.main(Main.java:11) Mar 10, 2014 2:54:36 PM JCP print SEVERE: null java.lang.IllegalArgumentException: Can not set int field hello.publicField2 to java.lang.Class at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:164) at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:168) at sun.reflect.UnsafeFieldAccessorImpl.ensureObj(UnsafeFieldAccessorImpl.java:55) at sun.reflect.UnsafeIntegerFieldAccessorImpl.getInt(UnsafeIntegerFieldAccessorImpl.java:56) at sun.reflect.UnsafeIntegerFieldAccessorImpl.get(UnsafeIntegerFieldAccessorImpl.java:36) at java.lang.reflect.Field.get(Field.java:379) at JCP.print(JCP.java:211) at JCP.start(JCP.java:36) at Main.main(Main.java:11) Mar 10, 2014 2:54:36 PM JCP print SEVERE: null java.lang.IllegalArgumentException: Can not set int field hello.publicField2 to java.lang.Class at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:164) at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:168) at sun.reflect.UnsafeFieldAccessorImpl.ensureObj(UnsafeFieldAccessorImpl.java:55) at sun.reflect.UnsafeIntegerFieldAccessorImpl.getInt(UnsafeIntegerFieldAccessorImpl.java:56) at sun.reflect.UnsafeIntegerFieldAccessorImpl.get(UnsafeIntegerFieldAccessorImpl.java:36) at java.lang.reflect.Field.get(Field.java:379) at JCP.print(JCP.java:219) at JCP.start(JCP.java:36) at Main.main(Main.java:11) 

Mainly its throwing all the exceptions at "fields[i].get(cl)", kindly help me figuring out where is the problem in getting the field values.

2 Answers 2

2

You have to use:

fields[i].get(obj) 

instead of:

fields[i].get(cl) 

because you are trying to get the value of this particular instance of the class, not the class itself.

Sign up to request clarification or add additional context in comments.

4 Comments

alright, but classes will keep on changing in the loop (upwards in hierarchy), and obj will be just one object of the initial class. I will have to make object of each class first or what?
@AbdulJabbar obj is an instance of the initial class, but it's also an instance of all the superclasses of this class, so you just use obj for everything, and it will work.
Thanks, it worked. Can you help me in the part "if the field is String", can't find anyway to find that like isString().
@AbdulJabbar if(fields[i].getType().equals(String.class)) should work.
1

You have few issues in that code in this part

if(fields[i].get(cl) == null) { System.out.print("Value: NULL"); } if(fields[i].getType().isPrimitive()) { System.out.println("Value: " + fields[i].get(cl)); } if(fields[i].getType().isArray()) { Object[] object=(Object[])fields[i].get(obj); System.out.print("Values: "); for(int j=0;j<object.length;j++){ System.out.print(object[j].toString() + ","); } } 

Fist is that you call the method on type instance instead of class.

fields[i].get(obj) should be fields[i].get(cl) and you repeat that, when you check the value for private. Also you use to much invocation. You can simplify code readability if you assign the results to local variables.

public void print(Object obj) throws IllegalArgumentException, IllegalAccessException { Class type = obj.getClass(); while(type != null) { System.out.printf("Class Name: %s ", type.getName()); System.out.println("FIELDS: "); for(Fiedl field : type.getFields()) { String modifier = Modifier.toString(field.getModifiers()); String name = field.getName(); System.out.printf("Modifiers: %s Name:%s\n",modifier,name); Object fieldValue = field.get(obj); Class<?> filedType = field.getType(); String printValue = null; if(fieldValue == null) { printValue = "NULL"; } else if(fieldType.isArray()) { printValue = Arrays.toString((Object[]) fieldValue); } else { printValue = String.valueOf(fieldValue); } System.out.printf("Value: %s",printValue); } System.out.println(); type = type.getSuperclass(); } } 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.