9

Let's say I have a class like this:

public static class Test {

    private Optional<String> something;

    public Optional<String> getSomething() {
        return something;
    }

    public void setSomething(Optional<String> something) {
        this.something = something;
    }
    
}

If I deserialize this JSON, I get an empty Optional:

{"something":null}

But if property is missing (in this case just empty JSON), I get null instead of Optional<T>. I could initialize fields by myself of course, but I think it would be better to have one mechanism for null and missing properties. So is there a way to make jackson deserialize missing properties as empty Optional<T>?

Artem Malinko
  • 1,761
  • 1
  • 22
  • 39
  • 2
    Looks like convenient way to distinguish between `null` and absent value for me – Alex Dvoretsky Feb 12 '17 at 21:08
  • Actually, I was googling exactly for a way how to differentiate cases when the field is presented in the JSON document but has `null` value, and when the field is missing. And it seems that's the only way to achieve that: empty optional - the field is here but has no value; no optional (==`null`) - the field is missing. – Roman Proshin Oct 08 '21 at 15:36

2 Answers2

6

For a solution without getters/setters, make sure something get initialized like this:

public Optional<String> something = Optional.empty();
gamliela
  • 3,447
  • 1
  • 35
  • 41
  • 1
    That's the only easy way to make jackson handles both null and missing values the same way – sam Apr 10 '20 at 13:01
4

Optional is not really meant to be used as a field but more as a return value. Why not have:

public static class Test {
  private String something;
  public Optional<String> getSomething() {
    return Optional.ofNullable(something);
  }
  public void setSomething(String something) {
    this.something = something;
  }
}
assylias
  • 321,522
  • 82
  • 660
  • 783
  • 3
    oracle does not think so http://www.oracle.com/technetwork/articles/java/java8-optional-2175753.html – AdamSkywalker Jan 27 '16 at 09:26
  • 2
    @AdamSkywalker depends on which source from Oracle - people who worked on the API [seem to think differently](http://stackoverflow.com/a/23464794/829571). – assylias Jan 27 '16 at 09:33
  • See also [Stephen Colebourne's view](http://blog.joda.org/2015/08/java-se-8-optional-pragmatic-approach.html) (who is behind Joda time and the java time API). – assylias Jan 27 '16 at 09:35
  • Wouldn't it be overhead to create new object every time someone calls a getter? – Artem Malinko Jan 27 '16 at 09:46
  • @ArtemMalinko: You could move the Optional creation into the setter, too. – Thilo Jan 27 '16 at 09:47
  • @Thilo then it will be a field:) And assylias sad that Optional is not really meant for it. – Artem Malinko Jan 27 '16 at 09:52
  • 2
    @ArtemMalinko I don't think the overhead is very material - if the few nanoseconds it takes to create and GC a short lived object is a concern in this class, you should probably not use Optional at all... You can profile your app to find the real impact, – assylias Jan 27 '16 at 09:56
  • @ArtemMalinko Do you think an `Optional` field comes without any cost? No new object will be created for empty Optionals btw. – a better oliver Jan 27 '16 at 10:03
  • @zeroflagL I think this cost will be multiplied by the number of method invocations. And I don't see any reason to have this overhead although I haven't read links yet. – Artem Malinko Jan 27 '16 at 10:07
  • I've read about using Optional and you're right. It's not designed to be a field(although I don't see why it would be bad, but it's another topic). Thank you, didn't know that this simple question would give me new information about jdk8 API. – Artem Malinko Jan 27 '16 at 10:31
  • @ArtemMalinko if you have many calls, it is likely that the calling code will be optimized by the JIT. I think it will be able to remove the `Optional` instantiation in most cases. – Didier L Jan 27 '16 at 12:24