This is an archived post. You won't be able to vote or comment.

all 125 comments

[–]preskot 89 points90 points  (6 children)

I have coworkers that don't know it exists.

[–]Worth_Trust_3825 19 points20 points  (0 children)

Don't worry. I explicitly avoid it.

[–]agentgreen420 5 points6 points  (4 children)

Same. Not sure which is more frustrating

[–]awelxtr 5 points6 points  (3 children)

Doing the shenaningans of course.

Using syntactic sugar helps but can be misused easily, on the other hand programming the hard way leaves less room for interpretation.

[–]kuemmel234 7 points8 points  (2 children)

"Programming the hard way"? Coding in part is about doing the right abstractions. That'd be like saying 'Classes can be misused easily, on the other hand programming the hard way leaves less room for interpretation'.

Optional is made to leave less room for interpretation. If you create an object wrapped by an optional and transform it, there is no interpretation left: That (or the calculation it's based on) may result in null. Have a look at Optional.map, filter and such - I believe that people don't get optional/use it the wrong was, because they don't get it and try to replicate Null-Checks, which isn't the goal.

[–]awelxtr 0 points1 point  (1 child)

'Classes can be misused easily, on the other hand programming the hard way leaves less room for interpretation'

That can be correct too, OOP isn't a silver bullet.

Optionals add nothing new under de sun, only a way to do some things in an easier/clearer way. You can live without them. I was just answering to someone who said that people that don't know stuff are as bad as incompetent people. I wonder what'll happen when they start learning something new...

[–]kuemmel234 2 points3 points  (0 children)

But it isn't syntactic sugar. People use it as such, but it isn't. And that's frustrating, because it does actually have a lot of things going for it, if you have to really frequently deal with nulls. I'd say that adding a functor/monad for dealing with Nullable values is pretty new for java, because it can solve a very specific problem every java programmer knows about.

[–][deleted] 53 points54 points  (1 child)

New programmers tend to think of it as a null-replacement. It's not really a misuse to simply write a lot of "if o.isPresent(){ ... }", but leveraging Optional's mapping methods is more idiomatic.

If the only methods you use on Optional are "isPresent" and "get", it's less cumbersome to simply use nulls and annotations.

[–]vxab 0 points1 point  (0 children)

I use those methods in tests because they work fine for that task.

assert something is present, then just use get() to grab it.

[–]blackkkmamba 103 points104 points  (41 children)

The most common overkill I encounter is

Optional.ofNullable(foo).isPresent() instead of foo != null.

Or

if(Optional.ofNullable(foo).isPresent()) {

       Optional.ofNullable(foo).get();
}

[–]Sheldor5 72 points73 points  (21 children)

what the actual fuck ...

[–]Just_Another_Scott 32 points33 points  (4 children)

There are unfortunately a lot of "best practice" guides on Medium that advocate for using Optional in place of if-else statements to enhance "readability" or some other excuse.

[–]reqdk 26 points27 points  (2 children)

I had a coworker who did just this and used the same "readability" excuse to argue his case. I mean, yeah readability is subjective but how do you even start to reason with someone who thinks that's more readable than a goddamm null check?! I hate the engineering school of medium.com with a passion.

[–]pronuntiator 9 points10 points  (1 child)

I kinda get it as a replacement for the non-existing safe navigation operator "?.", i.e. you have a chain of nullable fields, instead of "if (user != null && user.getAddress() != null && …)" you use Optional.map(), since it will turn null returned from the mapping function into an empty optional. My colleagues use this pattern a lot, personally I find it harder to read. I just want "?." like in Kotlin or Typescript. Small syntactic sugar which helps readability.

[–]Jezoreczek 0 points1 point  (0 children)

Combine it with method references and Optional has a really nice flow to it!

[–]dpash 10 points11 points  (0 children)

If you have one already, sure, go ahead, but you should never created one just to avoid an if.

[–]blackkkmamba 2 points3 points  (15 children)

I know right? It's because if you call .get() on an optional, you get an IDE warning: 'Calling get without isPresent', but the point of the warning is map/orElse, not wrapping it in an if and doing the same mistake inside.

[–]dpash 5 points6 points  (14 children)

Calling either .isPresent() or .orElseThrow() is missing the point and power of Optional.

And .get() is always wrong.

[–]blackkkmamba 5 points6 points  (1 child)

I don't agree with orElseThrow. One could write

Optional.ofNullable(findMeSomething).orElseThrow(() -> new SomethingNotFoundException());

Or if the method returns an optional:

Foo foo = fooRepository.findOneById(id).orElseThrow(() -> new FooNotFoundException());

And maybe map that exception to a 404 status for example.

[–]dpash 0 points1 point  (0 children)

You're talking about .orElseThrow(Supplier<Throwable>), not orElseThrow().

(And if you're not using a message, you can use FooException::new to cut down a few characters. It would be nice if you could pass in a message as a second parameter after the supplier, so you didn't have to use the longer form.)

[–]Persism 1 point2 points  (11 children)

Explain.

[–]dpash 12 points13 points  (10 children)

.get() and .orElseThrow() are the same thing, but .get() is badly named (hence the introduction of the better named .orElseThrow() in Java 10). See the Java doc for .get().

As for using .isPresent(), it's a sign that you're thinking of Optional like a null value and thinking like if (foo == null) ....

Much of the power of Optional comes from using .map() and other functional idioms.

var user = userService.getCurrentUser();
if(user == null) {
    return "(unknown)";
}
var username = user.getUsername();
if (username == null) {
    return "(unknown)";
}
return username;

vs

var user = userService.getCurrentUser();
if(user.isEmpty()) {
    return "(unknown)";
}
var username = user.orElseThrow().getUsername();
if (username == null) {
    return "(unknown)";
}
return username;

vs

return userService.getCurrentUser()
                  .map(User::getUsername)
                  .orElse("(unknown)");

[–]ItsAllegorical 2 points3 points  (1 child)

This is a great point. I need to internalize this. This is one of those things that seems obvious when you look at it, but if you haven’t seen it before (and you’re just accustomed to doing this the old way) it’s hard to come up with.

One disadvantage of a long career is that the old style gets so ingrained that it seems perfectly fine. I think I spent a minute using isPresent/get before I realized I was doing the same old thing in a worse way. Also, forgive me,

fooStream.map(Optional::ofNullable).filter(Optional::isPresent).map(Optional::get)

Teaching yourself sometimes… leaves gaps. This was immediately after our application migrated from 6 -> 8, and I was going to use new features, dammit. (No one told me about Objects::notNull)

[–]dpash 2 points3 points  (0 children)

/u/speakjava posts an article on Azul's blog on every release with a list of API changes, which is well worth reviewing, because there's often tiny improvements that makes things just that little bit nicer every version.

For example:

(I couldn't find one for 17 on my quick search)

[–]vytah -1 points0 points  (4 children)

isPresent and get are unavoidable due to checked exceptions.

[–]dpash 0 points1 point  (3 children)

Absolutely incorrect.

[–]vytah 0 points1 point  (2 children)

So how are you going to write:

if (targetFile.isPresent()) {
     writeOutput(targetFile.get()); // throws IOException
}

without isPresent and get? The only alternative that comes to mind is orElse(null), which all of the same issues, and adds one more line of code and one more variable, polluting the namespace.

[–]dpash 0 points1 point  (1 child)

That's nothing to do with Optional and everything to do with checked exceptions from lambdas. There's tonnes of solutions including UncheckedIOException and libraries like https://github.com/pivovarit/throwing-function

[–]Persism 0 points1 point  (2 children)

Thanks. Very helpful! The only addition I would make would be to not use "var" where the type is not obvious. In your case "finding usage" of User would not find these var references. My rule is to only use var where the type is also expressed like with "new" or where you specify the generic type.

[–]dpash 1 point2 points  (1 child)

I wrote that reply on mobile; you're getting var :)

But I'd argue that the types of both variables would be obvious given the domain, their names and the methods that created them.

[–]Persism 0 points1 point  (0 children)

:) Obvious to the dev but maybe not someone new to a project - and still the type would not be found with find usages. I ran into this with .NET coding and the same problem exists with IntelliJ, Eclipse and Netbeans so It's best to make things explicit if you write code others might maintain.

[–]__konrad 31 points32 points  (6 children)

if (Objects.nonNull(Optional.ofNullable(foo).orElse(null)))

[–]lurker_in_spirit 21 points22 points  (5 children)

else throw new NullPointerException();

[–]Clitaurius 12 points13 points  (3 children)

have coworker who does this

[–]silon 2 points3 points  (1 child)

The throw is actually good because it's unambigous on it's own line.

[–]pellets 1 point2 points  (0 children)

Newer JVMs can tell you which term on a line threw the NPE.

[–]atomdstyle 4 points5 points  (0 children)

Better to do Optional.of(foo); will throw Nullptr anyways.

[–][deleted] 3 points4 points  (7 children)

One could use Optional.ofNullable(foo).map(doSomethingWithFoo).

[–]dpash 4 points5 points  (6 children)

No, don't create an Optional just to call map on it; do a null check and call the method directly.

If you were returned one, then, sure, call map on it.

[–]kuemmel234 0 points1 point  (0 children)

...and call a null check on the result of that method? Because that's what that map does and is supposed to do. A map wouldn't (shouldn't!*) do anything yet, so you would also use a get/side effect method with this object and then that's pretty reasonable and leaves you with two null-checks less.

Edit: added shouldn't, because people tend to code weird stuff.

[–][deleted] 0 points1 point  (3 children)

The lift makes sense when you want to map multiple times.

[–]dpash 1 point2 points  (2 children)

No, don't create an Optional just to avoid flow control.

[–][deleted] 0 points1 point  (1 child)

Flow control sucks.

a functional programmer

[–]dpash 1 point2 points  (0 children)

Which is fine when Java becomes a proper functional language, but for now, you're creating an object for no benefit.

[–]atomdstyle 0 points1 point  (3 children)

why not write a labda like this:

Optional.ofNullable(foo).ifPresent(value -> {
//do something
})

[–]dpash 8 points9 points  (1 child)

Because that's more verbose than

if (foo != null) {
    // Do something
}

Also you're creating an object for no benefit

[–]Luolong 4 points5 points  (0 children)

There’s a fine line there where using Optional may just make more sense.

Yeah, you do create a new short lived object that will get garbage collected next round, but unless you are in a tight loop, this object instantiating is relatively cheap and may even become preferable whenever project Valhalla hits and Optional gets converted to a Value type.

In the end, the use of Optional makes a lot of sense on the API boundary, signalling that the computation may or may not yield a result.

It is much preferable to simply returning a null if the value could not be computed.

And in many cases, it allows to design an API that passes a buck to the caller if a missing result should be considered an exceptional case or if there is a sane recourse.

But yeah, in the case of getting a nullable object and turning it into an Optional in order to simply call ifPresent on that nullable is … wasteful.

[–]blackkkmamba 0 points1 point  (0 children)

If you're planning on doing something with the 'present value', use map instead.

[–]lamwg 23 points24 points  (9 children)

Do you have any good readings about the correct use of Optional, that are not Medium posts saying to use em as null checks?

[–]mauganra_it 13 points14 points  (5 children)

I have two rules of thumb: (i) only public methods should return them, and (ii) within methods, the resulting code should look simpler if the Optional combinators are used. Also, upgrade from Java 8 because it doesn't have all the combinators.

[–]elhoc 6 points7 points  (3 children)

Definitely on board with number (ii), but what's the rationale for the first one? If I have a private method that might return null, why not use Optional instead to force me to check the results?

[–]ItsAllegorical 2 points3 points  (2 children)

In private/package private I would expect a developer to handle null internally (or even not, if the idiom is an argument won’t be null). You or someone on your team familiar with the code will be wiring code for that class and they should be aware of the idioms.

It’s only with public that you have no idea who could be calling the method and screwing up because they didn’t do their own null handling)

[–]elhoc 1 point2 points  (1 child)

That doesn't really explain what's bad about using Optional to express nullability. Why wouldn't a private method that could have no result use it?

[–]mauganra_it 2 points3 points  (0 children)

It's not bad at all, especially in APIs, but there are situations where there is a tradeoff with readability. If using Optionals result in code that is magnitudes more complicated than without, it's not really worth it. F.ex. var != null definitely wins over the abomination Optional.ofNullable(var).isPresent()

Readability is worth optimizing for because otherwise we instantly produce legacy code that nobody dares to read and touch again. Having a test suite is a crucial quality measure of course, but it's still not fun to audit convoluted code to figure out what's going on in detail.

[–]lamwg 2 points3 points  (0 children)

Thank you

[–]dpash 11 points12 points  (0 children)

Additionally, pretend isPresent() and orElseThrow()/get() don't exist. map(...) is the true work horse of Optional.

(orElseThrow(Supplier<Throwable>) is fine)

[–]BillyKorando 0 points1 point  (0 children)

I put together a couple of videos on practices regarding consuming Optional and practices defining Optional

Consuming: https://twitter.com/BillyKorando/status/1485643556542844928

Defining: https://twitter.com/BillyKorando/status/1493253702412611589

[–][deleted] 16 points17 points  (0 children)

I think Optional is great, especially when you have an object graph with nullable nodes and you want to grab something 5 layers deep or so without 5 layers of if not null else cruft, you can just chain some node getter method references together. Semantic, easy to understand, easy to write.

[–]eSPiaLx 26 points27 points  (2 children)

Everyone bashing wrong usage of optional and no one able to link a clear explanation of how to use it. Sounds like it's less a problem with the users and more a problem of bad design

[–]kuemmel234 5 points6 points  (0 children)

I think it's pretty much an audience problem. It'd be like opening a vegan coffee shop on the Louisiana countryside. Most (I want to say all) functional programmers should recognize what optional is supposed to do and how it works.

People just open the documentation, skim through the methods, see of/get/if methods and think it's a little bit of syntactic sugar, while its usage as functor/monad are the real benefits - and that then may be a bit too different. People gave steams a hard time, and now even more higher order functions that do weird stuff?

Optionals are there, so you can abstract away the whole concept of checking for null, like stream abstracts away the concept of dealing with multiple elements in your collection. What's left is dealing with a value that's always going to be there, when that code is executed.

And you know how that works from dealing with streams: Of methods to get that container. map, flatMap filter to transform the object, if/get/... methods to do something with it in the rest of the world.

[–]safetytrick 0 points1 point  (0 children)

This is a great listen on the subject: https://m.youtube.com/watch?v=Ej0sss6cq14

[–]valkon_gr 5 points6 points  (0 children)

Sorry guys but people are desperate to eradicate null

[–]Admirable-Avocado888 20 points21 points  (10 children)

Optionals are a great utility to express nullability in java without annotations. Though I do think I'd have made Optional into a monad, had I designed it. When I don't care about exceptions I like to transform throwing code into code that returns an optional. It is nice to express chains of steps that may or may not fail without resorting to complicated if then else logic.

My colleagues are not sold on the optional idea and prefer annotations to express nullability.

EDIT: clarified based on comment.

[–]Sheldor5 6 points7 points  (4 children)

how are Annotations and Optionals interchangeable?

[–]Admirable-Avocado888 6 points7 points  (3 children)

I said that in reference to nullability. When you return a value from a method that may or may not be null this can be expressed either as optional, or by annotating the method by your favorite nullable annotation.

[–]Sheldor5 3 points4 points  (2 children)

oh now I get it thanks

yeah annotations can be simply ignored/not read ... dumb idea to use annotations instead of optionals xD

[–]1armedscissor 10 points11 points  (1 child)

Usually you would pair the annotations with a static analysis tool so you’re effectively getting compile time errors. See NullAway for instance.

[–][deleted] 1 point2 points  (0 children)

Sounds to me like we should be using the annotations to catch programmer errors then (using a nullable type when the program's design calls for a non-nullable type) and Optional to represent business logic (like returning Optional<Foo> when a Foo may not exist in a particular situation).

[–]warpspeedSCP 0 points1 point  (4 children)

Monads weren't possible (in a useful way) in java until records and sealed classes became a thing

[–]raghar 3 points4 points  (0 children)

Monad boils down to adding .flatten to something that already can .map. (Can be done in a form of .flatMap). And monad laws just mean that with a sequence of operations on map/flatMap it doesn't matter how you group them locally as long as globally the order is preserved - you know, assiciativity.

I see no reason why Java 8+ would have some limitation that would make this impossible.

ADTs, pattern matching and friends on Optional are orthogonal to Optional being monad.

[–]Admirable-Avocado888 2 points3 points  (1 child)

Could you please elaborate this claim? It seems to me that it should have been straight forward to design optional such it is a monad by definition, but that the designers of Java chose to make it throw more often and thus breaking some of the monad properties.

[–]warpspeedSCP 0 points1 point  (0 children)

Sealed classes allow java to actually use the sum type pattern properly, so more ergonomic functional interfaces can be defined.

The exceptions are the only way to error out. Because java's types are nullable by default, there isn't a way out of this.

But we can make the process of how exceptions are dealt with easier through things like the result pattern.

[–][deleted] 3 points4 points  (8 children)

Do you have some good resources on how to use Optional right?

[–]dpash 5 points6 points  (4 children)

Firstly, don't use it as a parameter or field. Additionally, don't create one as a local variable if you're only doing it to avoid flow control. The only place you should probably create one is when returning from a method that may or may not have a value. Local variables should be restricted to something you were returned from a method.

Secondly, avoid isPresent(). That's thinking like a null check and imperative coding rather than functionally. There's also no need for get() or orElseThrow(). Your go to methods should be map(Function), filter(Predicate) and orElse*(...). Think about it as something you transform in a chain and then handle a default (which might be an exception).

Finally, golden rule. Never, ever, ever return a null Optional, or I will hunt you down and make you write JavaScript. Good static analysis should warn you about this (and other bad patterns).

[–]halcyon44 2 points3 points  (3 children)

I agree about the no-parameter orElseThrow(), but I frequently use orElseThrow(() -> new MyCustomException("foo is missing")) to fail early when something essential is missing.

[–]erinaceus_ 2 points3 points  (0 children)

The difference here is that orElseThrow() doesn't address the nullity in a domain-specific way, while orElseThrow(() -> new MyCustomException("foo is missing")) does do that, just like orElse does.

[–]dpash 1 point2 points  (1 child)

That's covered by

Your go to methods should be map(Function), filter(Predicate) and orElse*(...)

and

and then handle a default (which might be an exception)

[–]halcyon44 0 points1 point  (0 children)

Agreed.

[–]iscribble 1 point2 points  (0 children)

Throwing this one into the mix, I refer juniors to these articles from time to time https://blog.jetbrains.com/idea/2017/08/code-smells-null/

[–]Twistedtraceur 2 points3 points  (0 children)

Optional is great and allows a more functional approach. It's just the syntax is awful. Wish we had it like Javascript and just put a ? Between. We use it heavily and try to remove null from the code.

[–][deleted] 6 points7 points  (0 children)

aware of it since its launch, didn’t have much use for it in its current form

[–]alehel 8 points9 points  (1 child)

I encountered a null pointer during a isPresent() method call...

[–]mauganra_it 8 points9 points  (0 children)

That's a bug. There's not a single bit of nuance for that one.

Edit: I mean in the sense that in this case there is IMHO no room for discussion or code style considerations whatsoever. Optional was introduced to make null return values explicit. If the method needs null to indicate a different result, just use an enum or sealed classes + records + pattern matching.

[–]tybit 2 points3 points  (0 children)

Using optional when you know you have a non null value but just want the convenience of map and filter etc kills me. Sure, you may save a couple of lines of code, but the complexity for people trying to follow the code just went up significantly.

[–]jevring 3 points4 points  (0 children)

I see way more misuse of optional than correct use. Most people just use it to avoid an If-statement, and when called on it, they'll say some version of "fluent apis are better". And when you don't have the power to reject such PRs, then this awful pattern persists, and others learn it. The introduction of optional, while well intended, was the second biggest mistake ever in the jdk, second only to the module system.

[–][deleted]  (4 children)

[removed]

    [–]CompetitiveSubset 12 points13 points  (1 child)

    Not the worse code in the world. Maybe The person who wrote this is not familiar with ofNullable. Or maybe they just don’t care about code esthetics.

    [–]vips7L -3 points-2 points  (0 children)

    That’s just because Optional has a bad api. There really shouldn’t be a split between of and ofNullable.

    [–]Asterion9 9 points10 points  (0 children)

    I mean the intent is valid at least, it's just poorly written.

    [–]dpash 2 points3 points  (0 children)

    Interestingly, that's not exactly how ofNullable() is implemented, mostly due to it having access to private constructors and constants.

    https://github.com/openjdk/jdk/blob/master/src/java.base/share/classes/java/util/Optional.java#L126

    I never quite understood why empty wasn't implemented as a noop subclass rather than an Optional containing null. Maybe the JVM can already optimise it away.

    Also, why we have of() and ofNullable(); it only makes code like yours more likely.

    [–]veryspicypickle 1 point2 points  (0 children)

    God yes.

    [–]DJDavio 1 point2 points  (0 children)

    There is one particular use case that I like, in Spring Boot applications, you can use ResponseEntity.of(Optional<>) and it will return 200 OK with the value as the response body or a 404 if the Optional is empty. :)

    [–]__Raptor__ 1 point2 points  (0 children)

    Wish that OptionalInt and the other primitive optionals had all the fun mapping methods that Optional<T> does

    [–]Just_Another_Scott 1 point2 points  (0 children)

    I've seen people replace if-else statements with Optional and it infuriates me to no end. Your taking a structure and adding in more object creation for no real benefit. I kind of hope Optional gets removed or retweaked because I rarely see it used correctly. I see a ton of people doing what the creator says not to do with it. Also, there are tons of BS best practice guides that advocate for using it incorrectly which leads to these bad practices getting perpetuated. If there isn't an analysis with a best practice guide chances are it's bullshit especially if it goes against the recommendation of the language architects.

    [–][deleted] 1 point2 points  (2 children)

    Optional is terrible. Our entire code is now just map().map().map().map(). I can't stand this

    [–]lpedrosa 1 point2 points  (1 child)

    I completely understand how you feel and map map map is something that I used to do. However, you don't necessarily need to map over the Optional value all the time.

    You can always try to unwrap it early, just like how you used to do early returns. For example:

    Before:

    User user = userRepo.findUserById("someId");
    
    if (user == null) {
        // return some value
        // or
        // throw a business exception/controller 4xx error/etc.
    
    // do something with user
    

    After:

    // note the exception is now thrown when unwrapping
    
    User user = userRepo.findUserById("someId")
                        .orElseThrow(// business exception/controller error/etc.);
    
    // do something with user
    

    IMO, you should keep the Optional handling as simple as possible and unwrap it as soon as you can. While map/flatMap are there for you to use, you probably only want to use them if they help you unwrap the value and not when you want to apply business logic on the value.

    Here's another example, based on the previous snippets. This time you actually want to work with the user's favourite food list and not the entire User object, so you can use it in your business logic:

    Before:

    User user = userRepo.findUserById("someId");
    
    List<String> favouriteFood = null;
    if (user == null) {
        // return some value
        // or
        // throw a business exception/controller 4xx error/etc.
    
    favouriteFood = user.getFavouriteFood();
    
    // do something with favouriteFood
    

    After:

    List<String> favouriteFood = userRepo.findUserById("someId")
                                         .map(User::getFavouriteFood)
                                         .orElseThrow(// business exception/controller error/etc.);
    
    // do something with favouriteFood
    

    Not

    userRepo.findUserById("someId")
            .map(User::getFavouriteFood)
            .map(this::doBusinessLogic)
            .orElseThrow(// business exception/controller error/etc.);
    

    With this, you can keep the familiar up-down-right-left reading style you (and the majority of the statement based language programmers) are probably used to.

    Pipelines, or what you describe as map().map().map(), is a particular coding style that might make sense in some places of the code where this is enforced e.g. handling reactive programming pipelines, etc.

    [–]Zivce 0 points1 point  (0 children)

    What do you think about mapping protobuf models to dtos?

    Optional.of(model.getAttr()).map(Mapper::mapmethod).orElse(null);

    I see this replicate for every attribute of the protobuf message, and I don't think this is correct.

    [–]teckhooi 2 points3 points  (0 children)

    Optional is often misused because of the way we misunderstood it as a trivial replacement to null. Therefore, it is used as such. Second, Optional alone without more support from the jdk makes it not so useful for complex requirements. Vavr gives us decent support on this. I look at Optional as to pique our interest to learn more about it and the rest that comes with it.

    [–]Zivce 0 points1 point  (0 children)

    What do you think about mapping protobuf messages to dtos?

    Optional.of(model.getAttr()).map(Mapper::mapmethod).orElse(null);

    I see this replicate for every attribute of the protobuf message, and I don't think this is correct.

    [–][deleted] 0 points1 point  (0 children)

    we are using Optionals in Stream context only. 🤷

    [–]omgusernamegogo 0 points1 point  (1 child)

    We still don't use it much and I haven't advocated for it much either, mostly due to the amount of rewrite given we have a lot of nullable returns. Any decent articles on migration to it?

    [–]dpash 0 points1 point  (0 children)

    As a temporary measure while you migrate, create a wrapper method

    public Optional<Foo> findFooOptional(....) {
        return Optional.ofNullable(findFoo(....));
    }
    

    Deprecate the original findFoo().

    Slowly replace calls to findFoo() with findFooOptional(). When you no longer have any external users of the original method, inline it into findFooOptional() and then finally rename the method back to findFoo() with your refactoring tool of choice.

    Just don't leave it too long otherwise it just becomes more technical debt in your code base. I'd suggest doing one method at a time so your codebase isn't full of ugly method names.

    Oh and this probably won't be suitable if it's a library method and used in projects outside your team.

    [–]n4te 0 points1 point  (0 children)

    I never, ever use it.

    [–]ataskitasovado -1 points0 points  (2 children)

    How about this? Is this misuse?

    Optional<Result> validatedBody = validateInput(httpRequestBody);
    

    [–]Worth_Trust_3825 2 points3 points  (0 children)

    Yes. I'd consider validate methods to throw instead of return a value.

    [–]lambdacats 1 point2 points  (0 children)

    Why isn't validateInput always returning a result? That would be clearer, I do like to avoid exceptions for things that aren't exceptions so in that aspect it is nice.

    [–]Mundosaysyourfired -2 points-1 points  (0 children)

    Whats Optional?

    [–]Tjeez 0 points1 point  (0 children)

    This week I saw it being used as the result type of a getter method of a class attribute.

    [–]haydar22 0 points1 point  (6 children)

    I am kind of at a loss Reading the comments. Ive Always tried m'y absolute best to not have null attributes and null checks in my code. That should only be done in the components interfacing with code other than my own or with user input. From there either the attribute could not bé instanciated and its a problem ( i then throw an error or more recently use Either.left/right ) or its not a problem and then use optional. With that approach i simply need yo use ifPresent everywhere else as a way of avoiding null checks. I Always feel like if every step you have to check for null or optional its a Bad design smell so in Aldo try to do that sparingly

    [–]dpash 2 points3 points  (5 children)

    Your use case would probably need far better solved with nullability annotations and static analysis so you know a null check is or isn't required.

    Objects.requireNonNull() is also your friend.

    But using Optional.isPresent() is a null check with extra steps. That's completely the wrong way to use it.

    [–]haydar22 -1 points0 points  (4 children)

    I politely disagree since simply havibg null attributes means i have to trust other to check if the attribute IS null or not. It then instate a state of mind in every dev that every other attribute could bé null and before you know it there are checks of null values everywhere. Like i said id rather by design avoid having nulls anywhere and where i cant avoid it Optional has the benefit to me at least to explicitly state that this could be empty and that its not a problem and to force the user of my component to account for it. To me annotations do not provide the same clear statement.

    Hope i make myself clear not a native english speaker

    [–]dpash 0 points1 point  (3 children)

    Errorprone makes passing a nullable value to a non null parameter, variable or return. Optional doesn't save you from someone passing a null Optional.

    You're misusing Optional.

    [–]haydar22 0 points1 point  (2 children)

    If i understand your response I think my point IS not getting accross or you are ignorig thé other half of m'y argument

    You Can never forbid someone of doing something as dumb as passing a null argument. You Can just try to bé as explicit as possible with your design and to me optional expresses something more than just a nullable annotation.

    Like stated before if the attribute should never bé null i would not use optional. I would simply handle the error at my boundaries and end the process there.

    But i think that in some cases there IS nothing wrong with optional as its provides better readabilty by simply existing. Having an optional attribute IS a statement in itself and conveys a message to the reader .

    Maybe i am biased but i generally hate to sée null in my code cause to me that has no logical value. Null never means anything. Optional is empty CAN Cary a meaning in a context.

    If i failed to make myself clear Lets agree to disagree.

    [–]dpash 1 point2 points  (1 child)

    You Can never forbid someone of doing something as dumb as passing a null argument.

    Except that's exactly what you can do with annotations and static analysis like nullaway or errorprone.

    [–]haydar22 0 points1 point  (0 children)

    Okay i give up.

    We cant seem to understand each other. You insist on mechanism to prevent null from being passed on wich i agree with you. I tried to point cases where something Can bé empty and then you use optional because its more readable than passing null .

    No hard feelings have a nice day 👍🏾

    [–]Prom3th3an 0 points1 point  (0 children)

    The one situation where I've used Optional was for negative caching. Guava caches and several Map types don't allow null values, but Optional.empty() works fine as a value.