Pergunta

I am trying to fetch Field name as well as field value using Reflection.

I am passing dynamic classes as per operation needed.

I have made a method to fetch field name and value, i am getting field name but not getting field value. when I am using following code it gives me an error java.lang.IllegalAccessException stating that can not access private member of class.

Following is my UPDATED code :

public String SerializeCommand(ICommand command){

    StringBuilder command_text = new StringBuilder();
    Field [] f = command.getClass().getDeclaredFields();
    for(Field field : f){
        field.setAccessible(true);
        command_text.append(field.getName() + ",");
        try {
            System.out.println(field.get(command.getClass()));
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }
    return command_text.toString();
}

Here ICommand is a class name for it, suppose if operation is add then add class will be passed.

Any Idea what to do to solve this problem.

Foi útil?

Solução 2

Please try this code.

public String SerializeCommand(ICommand command){

    StringBuilder command_text = new StringBuilder();
    Field [] f = command.getClass().getDeclaredFields();
    try{
    for(Field field : f){
        field.setAccessible(true);
        command_text.append(field.getName() + ",");
        System.out.println("Value :: " + field.get(command));
    }
    }catch(IllegalArgumentException e){
        e.printStackTrace();
    } catch (IllegalAccessException e) {
        e.printStackTrace();
    }
    return command_text.toString();
}

Outras dicas

Instead of command.getClass() pass the object of command class. The value contains by object not by class

Java also takes care of not being able to access private members, even when doing it via reflection. But constructors, methods, and fields are AccessibleObjects, which provides a method to flag the member as being accessible although it might be private:

field.setAccessible(true);

Afterwards you can read it and even set a new value on it.


An edit to make it clear. Consider the following simple record class:

public class Record {
    private int length;
    private String name;
    public Record(int length, String name) {
        this.length = length;
        this.name = name;
    }
    public int getLength() { return length; }
    public String getName() { return name; }
}

And now let's write a reflection test program:

public class ReflectionTest {
    public static void main(String[] args) throws Exception {
        Record record = new Record(42, "42");
        Field[] fields = record.getClass().getDeclaredFields();
        for (Field field : fields) {
            System.out.println(field.getName() + " => " + field.get(record));
        }
    }
}

This will result in an IllegalAccessException, as the private fields cannot be accessed. Now change the foreach loop a little:

        for (Field field : fields) {
            field.setAccessible(true);
            System.out.println(field.getName() + " => " + field.get(record));
        }

This time you will see expected output:

length => 42

name => 42

Your mistake also was to call the get method on the class and not on the object. This would be like this little modification:

        for (Field field : fields) {
            field.setAccessible(true);
            System.out.println(field.getName() + " => " + field.get(record.getClass()));
        }

This time you will see an IllegalArgumentException (not an IllegalAccessException).

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top