DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Last call! Secure your stack and shape the future! Help dev teams across the globe navigate their software supply chain security challenges.

Modernize your data layer. Learn how to design cloud-native database architectures to meet the evolving demands of AI and GenAI workloads.

Releasing software shouldn't be stressful or risky. Learn how to leverage progressive delivery techniques to ensure safer deployments.

Avoid machine learning mistakes and boost model performance! Discover key ML patterns, anti-patterns, data strategies, and more.

Related

  • Unraveling Lombok's Code Design Pitfalls: Exploring Encapsulation Issues
  • Legacy Code Refactoring: Tips, Steps, and Best Practices
  • Two Cool Java Frameworks You Probably Don’t Need
  • How To Build a Multi-Zone Java App in Days With Vaadin, YugabyteDB, and Heroku

Trending

  • The Role of Functional Programming in Modern Software Development
  • Apache Doris vs Elasticsearch: An In-Depth Comparative Analysis
  • Customer 360: Fraud Detection in Fintech With PySpark and ML
  • Unlocking the Benefits of a Private API in AWS API Gateway
  1. DZone
  2. Coding
  3. Java
  4. Java 8 Optional - Avoid Null and NullPointerException Altogether - and Keep It Pretty

Java 8 Optional - Avoid Null and NullPointerException Altogether - and Keep It Pretty

By 
Yannick Majoros user avatar
Yannick Majoros
·
Sep. 27, 14 · Interview
Likes (9)
Comment
Save
Tweet
Share
200.6K Views

Join the DZone community and get the full member experience.

Join For Free

There have been a couple of articles on null, NPE's and how to avoid them. They make some point, but could stress the easy, safe, beautiful aspects of Java 8's Optional. This article shows some way of dealing with optional values, without additional utility code.

The old way

Let's consider this code:

String unsafeTypeDirName = project.getApplicationType().getTypeDirName();
System.out.println(unsafeTypeDirName);

This can obviously break with NullPointerException if any term is null.

A typical way of avoiding this:

// safe, ugly, omission-prone
if (project != null) {
    ApplicationType applicationType = project.getApplicationType();
    if (applicationType != null) {
        String typeDirName = applicationType.getTypeDirName();
        if (typeDirName != null) {
            System.out.println(typeDirName);
        }
    }
}

This won't explode, but is just ugly, and it's easy to avoid some null check.

Java 8

Let's try with Java 8's Optional:

// let's assume you will get this from your model in the future; in the meantime...
Optional<Project> optionalProject = Optional.ofNullable(project);

// safe, java 8, but still ugly and omission-prone
if (optionalProject.isPresent()) {
    ApplicationType applicationType = optionalProject.get().getApplicationType();
    Optional<ApplicationType> optionalApplicationType = Optional.ofNullable(applicationType);
    if (optionalApplicationType.isPresent()) {
        String typeDirName = optionalApplicationType.get().getTypeDirName();
        Optional<String> optionalTypeDirName = Optional.ofNullable(typeDirName);
        if (optionalTypeDirName.isPresent()) {
            System.out.println(optionalTypeDirName);
        }
}

As noted in a lot of posts, this isn't a lot better than null checks. Some argue that it makes your intent clear. I don't see any big difference, most null checks being pretty obvious on those kind of situations.

Ok, let's use the functional interfaces and get more power from Optional:

// safe, prettier
Optional<String> optionalTypeDirName = optionalProject
        .flatMap(project -> project.getApplicationTypeOptional())
        .flatMap(applicationType -> applicationType.getTypeDirNameOptional());
optionalTypeDirName.ifPresent(typeDirName -> System.out.println(typeDirName));

flatMap() will always return an Optional, so no nulls possible here, and you avoid having to wrap/unwrap to Optional.

Please note that I added *Optional() methods in the types for that. There are other ways to do it (map + flatMap to Optional::ofNullable is one). The best one: only return optional value where it makes sense: if you know the value will always be provided, make it non-optional. By the way, this advice works for old style null checks too.

ifPresent() will only run the code if it's there. No default or anything.

Let's just use member references to express the same in a tight way:

// safe, yet prettier
optionalProject
        .flatMap(Project::getApplicationTypeOptional)
        .flatMap(ApplicationType::getTypeDirNameOptional)
        .ifPresent(System.out::println);

Or if you know that  Project has an ApplicationType anyway:

// safe, yet prettier
optionalProject
        .map(Project::getApplicationType)
        .flatMap(ApplicationType::getTypeDirNameOptional)
        .ifPresent(System.out::println);


Conclusion

By using Optional, and never working with null, you could avoid null checks altogether. Since they aren't needed, you also avoid omitting a null check leading to NPEs. Still, make sure that values returned from legacy code (Map, ...), which can be null, are wrapped asap in Optional.

Java (programming language) IT

Opinions expressed by DZone contributors are their own.

Related

  • Unraveling Lombok's Code Design Pitfalls: Exploring Encapsulation Issues
  • Legacy Code Refactoring: Tips, Steps, and Best Practices
  • Two Cool Java Frameworks You Probably Don’t Need
  • How To Build a Multi-Zone Java App in Days With Vaadin, YugabyteDB, and Heroku

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!