49

I have read something about the purpose of Optional (unfortunately I don't remember where) in Java 8, and I was surprised the writer didn't mention the use of an Optional as an attribute in a class.

Since I am using optionals pretty frequently in my classes, I was wondering if this is a good practice. Or could I better just use normal attributes, which return null when they are not set?

Note: It may look like my question is opinion based, but I get the feeling using Optional in a class is really not the way to go (after reading the mentioned post). However, I like to use it and can't find any downside of using it.

Example

I would like to give an example to clarify. I have a class Transaction, which is built like this:

public class Transaction {
    
     private Optional<Customer> customer = Optional.empty();
     ....

vs

public class Transaction {
    
     private Customer customer = null;
     ....

When checking on a Customer, I think it is most logical to use transaction.getCustomer().isPresent() than transaction.getCustomer() != null. In my opinion the first code is cleaner than the second one.

swpalmer
  • 3,890
  • 2
  • 23
  • 31
bashoogzaad
  • 4,611
  • 8
  • 40
  • 65
  • @AdamSiemion Are we talking about Guava's `Optional` or Java 8's `Optional` here? – Jesper Mar 13 '15 at 13:44
  • @AdamSiemion Thanks for the link! I am not that experienced so did not know Guava already had it. However, the main reason mentioned there is that `Optional` has three possibilities: present, absent and null. Java 8 has so absent anymore, so that argument is not valid anymore.. – bashoogzaad Mar 13 '15 at 13:45
  • @bashoogzaad Whether there are three (null,absent,present) or two options (null/empty,present) it does not change the purpose of `Optional`. – Adam Siemion Mar 13 '15 at 13:57
  • 2
    @Jesper I think the purpose of `Optional` is the same in both Guava and Java 8, no? – Adam Siemion Mar 13 '15 at 13:59
  • @AdamSiemion The designers of Java 8 `Optional` had a clear idea of what it would be used for (see my answer). The designers of Guava probably had a different idea. Guava's `Optional` indeed implements `Serializable` while Java 8's `Optional` does not, which indicates that Guava's `Optional` might be more suitable for fields than Java 8's. – Jesper Mar 13 '15 at 14:33
  • @Jesper Guava `Optional` was released in 2011. Java 8 was released in 2014. My guess is that Java 8 `Optional` was _at least_ influenced by Guava `Optional`. However since I have no evidence of that, I will no longer continue this thread. Thanks for the discussion. – Adam Siemion Mar 13 '15 at 14:56
  • Thanks all for the info, it is clear to me now!! – bashoogzaad Mar 13 '15 at 15:00
  • See also http://stackoverflow.com/a/24564612/2711488 – Holger Mar 13 '15 at 15:02

2 Answers2

71

Java 8's Optional was mainly intended for return values from methods, and not for properties of Java classes, as described in Optional in Java SE 8:

Of course, people will do what they want. But we did have a clear intention when adding this feature, and it was not to be a general purpose Maybe or Some type, as much as many people would have liked us to do so. Our intention was to provide a limited mechanism for library method return types where there needed to be a clear way to represent "no result", and using null for such was overwhelmingly likely to cause errors.

The key here is the focus on use as a return type. The class is definitively not intended for use as a property of a Java Bean. Witness to this is that Optional does not implement Serializable, which is generally necessary for widespread use as a property of an object.

Community
  • 1
  • 1
Jesper
  • 202,709
  • 46
  • 318
  • 350
  • Thanks for your answer! It is really helpful to know what the creators intended with `Optional`. The argument about the implementation of `Serializable` is not totally clear to me, but that's my fault, because I don't use it. – bashoogzaad Mar 13 '15 at 13:54
  • 24
    The funny thing about the blog you have linked is that the part you cited is a cite of [a StackOverflow answer](http://stackoverflow.com/a/26328555/2711488) – Holger Mar 13 '15 at 14:57
  • 4
    It would better be "general purpose". Are they saying, they introduced a workaround, where a perfectly general concept could be used instead? – Basilevs Mar 16 '18 at 04:12
  • 14
    Comming from scala I don't really understand why something that solves problems perfectly can't be used because the inventor specified it's main usage differently. I stumbled over this "issue" currently by reading Java code that has TDOs with nullable properties and each usage of these properties are wrapped in an Optional instead of directly defining the property as Optional. So I only see downsides instead of any benefit – rmmjohann Nov 20 '19 at 14:26
  • 9
    Strongly disagree, despite what they intended, Java Optionals are fantastic for exactly this purpose. The only downside is serialization which is easily addressable with most modern serialization libraries (Jackson's Jdk8Module for example). Using Optionals in this way results in cleaner client code (Optional.map/orElse/ifPresent) and makes it impossible to accidentally forget something is nullable. The creator of null references himself calls it his billion-dollar mistake: https://www.infoq.com/presentations/Null-References-The-Billion-Dollar-Mistake-Tony-Hoare/ – sichinumi Feb 16 '21 at 01:02
  • @sichinumi you can disagree but I'm quoting the designers of class Optional themselves (Brian Goetz from Oracle), you can of course choose to use it in a way that it was not intended, that's up to you... – Jesper Feb 16 '21 at 10:27
  • 2
    In fact, some classes of the jdk **do use** `Optional`'s as fields (e.g. ImmutableHttpRequest, HttpResponseImpl, ...). So I guess there are use cases when it is acceptable to do so, even if it is not recommanded in general. – Dartz Mar 22 '22 at 11:00
  • 2
    @Jesper And Java wasn't originally intended for writing complex server application stacks, but here we are. *Things do not just do what their creator intended.* – Donal Fellows Sep 12 '22 at 13:03
5

I think it is a theoretical question.

The notion of optional values was brought from functional languages world. Those languages usually also support pattern matching on language level and allow you to pattern match on the optional value.

In functional languages function calls usually return an optional value that other code could pattern match on.

I have never seen passing an optional as argument, but that does not mean it is a bad think. It looks weird though.

Crazyjavahacking
  • 9,343
  • 2
  • 31
  • 40
  • 1
    Thanks for your answer! I understand that it is particularly useful in eg lambda expressions, and if I understand you correctly, you also think it is a good practice to use it as an attribute? – bashoogzaad Mar 13 '15 at 13:53