Java Reflection get the Instance from a Field

2019-04-23 14:50发布

问题:

is there any way to get the Instance from a Field?
Here's a sample code:

public class Apple {
    // ... a bunch of stuffs..
}

public class Person {
    @MyAnnotation(value=123)
    private Apple apple;
}

public class AppleList {
    public add(Apple apple) {
        //...
    }
}

public class Main {
    public static void main(String args[]) {
        Person person = new Person();
        Field field = person.getClass().getDeclaredField("apple");

        // Do some random stuffs with the annotation ...

        AppleList appleList = new AppleList();

        // Now I want to add the "apple" instance into appleList, which I think
        // that is inside of field.

        appleList.add( .. . // how do I add it here? is it possible?

        // I can't do .. .add( field );
        // nor .add( (Apple) field );
    }
}

I need to use Reflection, because I'm using it with annotations. This is just a "sample", the method AppleList.add(Apple apple) is actually called by getting the method from the class, and then invoking it.

and doing so, like: method.invoke( appleList, field );

causes: java.lang.IllegalArgumentException: argument type mismatch

*EDIT* This might be helpful for someone who's looking for the same thing.

if the class Person, had 2 or more Apple variables:

public class Person {
    private Apple appleOne;
    private Apple appleTwo;
    private Apple appleThree;
}

when I get the Field, like:

Person person = new Person();
// populate person
Field field = person.getClass().getDeclaredField("appleTwo");
// and now I'm getting the instance...
Apple apple = (Apple) field.get( person );
// this will actually get me the instance "appleTwo"
// because of the field itself...

at the beginning, by looking at the line alone: (Apple) field.get( person );
made me think that it would go and get an Instance which matches Apple class.
that's why I wondered: "which Apple will it return?"

回答1:

The field isn't an apple itself - it's just a field. As it's an instance field, you need an instance of the declaring class before you can get a value. You want:

Apple apple = (Apple) field.get(person);

... after the apple field is populated for the instanced referred to be person, of course.