An Optional always contains a non-null value or is empty, yes, but you don't have an Optional, you have a reference of type Optional pointing to null. You need to initialize testString, e.g. to Optional.empty().
Optional isn't magic, it's an object like any other, and the Optional reference itself can be null. It's the contents of the Optional that can't be null.
An Optional always contains a non-null value or is empty, yes, but you don't have an Optional, you have a reference of type Optional pointing to null. You need to initialize testString, e.g. to Optional.empty().
Optional isn't magic, it's an object like any other, and the Optional reference itself can be null. It's the contents of the Optional that can't be null.
From the oracle documentation for the Optional type :
A container object which may or may not contain a non-null value.
So, yes it will return null if the variable is set to null. More info here
Since the whole purpose of Optional is to represent values that might not exist, why does the constructor of Optional require a non-null value? Is it becuase they wanted to coalesce all empty Optionals down to a single instance? Even if that's true, why not make Optional.of() behave the way Optional.ofNullable() and do away with the ofNullable() method?
Edit to clarify my opinion and respond to some of the points raised:
My opinion stated clearly, is only two "constructor" methods should exist:
of (and it should work like the current ofNullable method)
empty
So far the arguments against my opinion have been:
Having .of() and .ofNullable() makes it clear at the point of construction when the value exists and when it might not exist.
This is true, but that clarity is redundant. For safety, the call to .of() will either be inside the not-null branch of a null-check, or come after a not-null assertion. So even if .of() behaved as .ofNullable() does it would be clear that the value exists.
2. It guards against changes in behavior of the the methods supplying the values. If one of the supplying methods suddenly changes from never returning nulls to sometime returning nulls it will catch the error.
I would argue that guarding against this occurrence is the responsibility of the function returning the Optional values, and not the responsibility of Optional. If the function needs to guard against a null value so that it can handle it in some fashion (eg. by calling another supplier method) then then it needs to implement the not-null assertion explicitly in the body of its code. This is more clear than relying on an class called Optional do something that is semantically at odds with the plain reading of its class name.
In the case where the function doesn't care whether the value returned from the supplier is null or not, it should simply be able to call .of() to create the optional and return it.
In practice, why is this useful?
For example let's say you have this stream of integers and you're doing a filtering:
int x = IntStream.of(1, -3, 5)
.filter(x -> x % 2 == 0)
.findFirst(); //hypothetical assuming that there's no Optional in the API
You don't know in advance that the filter operation will remove all the values in the Stream.
Assume that there would be no Optional in the API. In this case, what should findFirst return?
The only possible way would be to throw an exception such as NoSuchElementException, which is IMO rather annoying, as I don't think it should stop the execution of your program (or you'd have to catch the exception, not very convenient either) and the filtering criteria could be more complex than that.
With the use of Optional, it's up to the caller to check whether the Optional is empty or not (i.e if your computation resulted in a value or not).
With reference type, you could also return null (but null could be a possible value in the case you filter only null values; so we're back to the exception case).
Concerning non-stream usages, in addition to prevent NPE, I think it also helps to design a more explicit API saying that the value may be present or not. For example consider this class:
class Car {
RadioCar radioCar; //may be null or not
public Optional<RadioCar> getRadioCar() {
return Optional.ofNullable(radioCar);
}
}
Here you are clearly saying to the caller that the radio in the car is optional, it might be or not there.
When Java was first designed it was common practice to use a special value, usually called null to indicate special circumstances like I couldn't find what you were looking for. This practice was adopted by Java.
Since then it has been suggested that this practice should be considered an anti-pattern, especially for objects, because it means that you have to litter your code with null checks to achieve reliability and stability. It is also a pain when you want to put null into a collection for example.
The modern attitude is to use a special object that may or may not hold a value. This way you can safely create one and just not fill it with anything. Here you are seeing Java 8 encouraging this best-practice by providing an Optional object.
Style 2 isn't going Java 8 enough to see the full benefit. You don't want the if ... use at all. See Oracle's examples. Taking their advice, we get:
Style 3
// Changed EmployeeServive to return an optional, no more nulls!
Optional<Employee> employee = employeeServive.getEmployee();
employee.ifPresent(e -> System.out.println(e.getId()));
Or a more lengthy snippet
Optional<Employee> employee = employeeServive.getEmployee();
// Sometimes an Employee has forgotten to write an up-to-date timesheet
Optional<Timesheet> timesheet = employee.flatMap(Employee::askForCurrentTimesheet);
// We don't want to do the heavyweight action of creating a new estimate if it will just be discarded
client.bill(timesheet.orElseGet(EstimatedTimesheet::new));
If you're using Optional as a "compatibility" layer between an older API that may still return null, it may be helpful to create the (non-empty) Optional at the latest stage that you're sure that you have something. E.g., where you wrote:
Optional<Employee> employeeOptional = Optional.ofNullable(employeeService.getEmployee()); if(employeeOptional.isPresent()){ Employee employeeOptional= employeeOptional.get(); System.out.println(employee.getId()); }
I'd opt toward:
Optional.of(employeeService) // definitely have the service
.map(EmployeeService::getEmployee) // getEmployee() might return null
.map(Employee::getId) // get ID from employee if there is one
.ifPresent(System.out::println); // and if there is an ID, print it
The point is that you know that there's a non-null employee service, so you can wrap that up in an Optional with Optional.of(). Then, when you call getEmployee() on that, you may or may not get an employee. That employee may (or, possibly, may not) have an ID. Then, if you ended up with an ID, you want to print it.
There's no need to explicitly check for any null, presence, etc., in this code.
you can returning Optional<Foo> from getForCode(final Integer code) and let the client deal with the optional value returned.
public static Optional<Foo> getForCode(final Integer code) {
return Optional.ofNullable(code).map(FOO_MAP::get);
}
Without changing the behavior of the original function, I don't think Optional buys you anything here, except the opportunity to bury some complex conditionals within its methods and lambdas. If you were to minimize the conditional expressions, using if-statements and boolean expressions, you'd end up with this:
Foo getForCode(Integer code) {
Foo foo = null;
if (code == null || (foo = FOO_MAP.get(code)) != null) {
return foo;
} else {
throw new IllegalStateException("Unknown foo for code: " + code);
}
}
This is a tad more readable than any solution using Optional, to my eye, though it's still pretty obscure.
If you're willing to change the semantics of the function, and to return an Optional, then the suggestion from Roshane Perera seems like a reasonable approach (+1).
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 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.
For example, you probably should never use it for something that returns an array of results, or a list of results; instead return an empty array or list. You should almost never use it as a field of something or a method parameter.
I think routinely using it as a return value for getters would definitely be over-use.
There's nothing wrong with Optional that it should be avoided, it's just not what many people wish it were, and accordingly we were fairly concerned about the risk of zealous over-use.
(Public service announcement: NEVER call Optional.get unless you can prove it will never be null; instead use one of the safe methods like orElse or ifPresent. In retrospect, we should have called get something like getOrElseThrowNoSuchElementException or something that made it far clearer that this was a highly dangerous method that undermined the whole purpose of Optional in the first place. Lesson learned. (UPDATE: Java 10 has Optional.orElseThrow(), which is semantically equivalent to get(), but whose name is more appropriate.))
After doing a bit of research of my own, I've come across a number of things that might suggest when this is appropriate. The most authoritative being the following quote from an Oracle article:
"It is important to note that the intention of the Optional class is not to replace every single null reference. Instead, its purpose is to help design more-comprehensible APIs so that by just reading the signature of a method, you can tell whether you can expect an optional value. This forces you to actively unwrap an Optional to deal with the absence of a value." - Tired of Null Pointer Exceptions? Consider Using Java SE 8's Optional!
I also found this excerpt from Java 8 Optional: How to use it
"Optional is not meant to be used in these contexts, as it won't buy us anything:
- in the domain model layer (not serializable)
- in DTOs (same reason)
- in input parameters of methods
- in constructor parameters"
Which also seems to raise some valid points.
I wasn't able to find any negative connotations or red flags to suggest that Optional should be avoided. I think the general idea is, if it's helpful or improves the usability of your API, use it.
Optional harnesses the type system for doing work that you'd otherwise have to do all in your head: remembering whether or not a given reference may be null. This is good. It's always smart to let the compiler handle boring drugework, and reserve human thought for creative, interesting work.
Without Optional, every reference in your code is like an unexploded bomb. Accessing it may do something useful, or else it may terminate your program wth an exception.
With Optional and without null, every access to a normal reference succeeds, and every reference to an Optional succeeds unless it's unset and you failed to check for that. That is a huge win in maintainability.
Unfortunately, most languages that now offer Optional haven't abolished null, so you can only profit from the concept by instituting a strict policy of "absolutely no null, ever". Therefore, Optional in e.g. Java is not as compelling as it should ideally be.
An Optional brings stronger typing into operations that may fail, as the other answers have covered, but that is far from the most interesting or valuable thing Optionals bring to the table. Much more useful is the ability to delay or avoid checking for failure, and to easily compose many operations that may fail.
Consider if you had your optional variable from your example code, then you had to perform two additional steps that each might potentially fail. If any step along the way fails, you want to return a default value instead. Using Optionals correctly, you end up with something like this:
return optional.flatMap(x -> x.anotherOptionalStep())
.flatMap(x -> x.yetAnotherOptionalStep())
.orElse(defaultValue);
With null I would have had to check three times for null before proceeding, which adds a lot of complexity and maintenance headaches to the code. Optionals have that check built in to the flatMap and orElse functions.
Note I didn't call isPresent once, which you should think of as a code smell when using Optionals. That doesn't necessarily mean you should never use isPresent, just that you should heavily scrutinize any code that does, to see if there is a better way. Otherwise, you're right, you're only getting a marginal type safety benefit over using null.
Also note that I'm not as worried about encapsulating this all into one function, in order to protect other parts of my code from null pointers from intermediate results. If it makes more sense to have my .orElse(defaultValue) in another function for example, I have much fewer qualms about putting it there, and it's much easier to compose the operations between different functions as needed.
You could use orElse(null):
String o = getOptional().orElse(null);
if (o == null) {
return;
}
You can use ifPresent and map methods instead, if the function is void and you need to do side-effects you can use ifPresent,
optional.ifPresent(System.out::println);
If another method return relies on the Optional than that method might need to return an Optional as well and use the map method
Optional<Integer> getLength(){
Optional<String> hi = Optional.of("hi");
return hi.map(String::length)
}
Most of the time when you call isPresent and get, you are misusing Optional.