vendredi 8 septembre 2017

What reflection mechanism does Jackson ObjectMapper use to modify a `final` field?

The ability of the Jackson ObjectMapper to construct an object and modify a final field post-initialization can be demonstrated by this simple code:

public class jsonNodeApp {
    public static void main(String[] args) throws Exception{
        ObjectMapper mapper=new ObjectMapper();

        Apple apple = mapper.readValue(new File("myapple.json"), Apple.class); //apple.seeds is 10, not -200
        System.out.println("Look what you made me do.");
    }
}

class Apple {
    final int seeds;

    Apple(){ //invoked by ObjectMapper
        System.out.println("Sole constructor invoked");
        seeds = -200;
    }

    public int getSeeds() { //never called, but existence required by ObjectMapper
        System.out.println("Placeholder getter"); 
        return 7676;
    }
}

And myapple.json simply contains {"seeds":10}.

I thought ObjectMapper would do something like that suggested here, but a search in the source for Modifier.FINAL was not fruitful.

So how does ObjectMapper do this particular trick?

Disclaimer: The industrial application of this feature is likely limited, and mine is not one of them. I am simply asking out of curiosity.





Aucun commentaire:

Enregistrer un commentaire