2

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.

flow2k
  • 3,999
  • 40
  • 55
  • Likely [here](https://github.com/FasterXML/jackson-databind/blob/33840a208b04f0eea79e4154cc160c9839768d3d/src/main/java/com/fasterxml/jackson/databind/introspect/POJOPropertiesCollector.java#L441). (I will reply separately to your comment later, I have to review, it's been a long time.) – Sotirios Delimanolis Sep 08 '17 at 22:56
  • It looks like if a field is final, it does some kind of "pruning" - not sure what this entails; I would think it would have to set the field somehow. I'll need to look into it more closely. Thanks. – flow2k Sep 08 '17 at 23:31
  • 1
    That method is meant to collect the fields as properties. During deserialization, it will use the corresponding `Field` objects to set the instance variables. `setAccessible` is sufficient to make the instance field writable. – Sotirios Delimanolis Sep 08 '17 at 23:48
  • It does that [here](https://github.com/FasterXML/jackson-databind/blob/33840a208b04f0eea79e4154cc160c9839768d3d/src/main/java/com/fasterxml/jackson/databind/deser/impl/PropertyBasedCreator.java#L198), in this case. – Sotirios Delimanolis Sep 08 '17 at 23:49
  • Also see [this](https://stackoverflow.com/a/18124662/438154) for the distinction between instance variables and static, class variables. – Sotirios Delimanolis Sep 08 '17 at 23:51
  • Very helpful - thanks @SotiriosDelimanolis. – flow2k Sep 09 '17 at 22:01

0 Answers0