0

I would like to use Java 11's Optional to protect myself from the dreaded null pointer exception. I wrote a basic test to check my understanding of how they work. like. so

   @Test
   public void optionalsWorkingAsExpected() {
       String x = null;
       var y = Optional.ofNullable(x.toString().toLowerCase()).orElse(null);
       assertThat(y).isNull();
   }

However this test failed with yet another null pointer exception saying

Cannot invoke "String.toString()" because "x" is null

For context what I want to be able to do is use a function chain like this:

myClass.getMyData().transformData().getName()

any of these function calls could result in being null and they are chained. I don't really care which one is null in the chain but if any of them is I want to return null to my variable. like so

String name = Optional.ofNullable(myClass.getMyData.transformMyData.getName()).orElse(null);

Any suggestions?

codernoob8
  • 434
  • 1
  • 9
  • 24
  • 2
    Does this answer your question? [Check chains of "get" calls for null](https://stackoverflow.com/questions/3458451/check-chains-of-get-calls-for-null) – happy songs Mar 10 '23 at 00:54
  • It is worth noting that a better design is to avoid null values entirely. You should design your objects so they avoid returning null at all, as much as possible. In particular, *never* return null as a synonym for an empty String, array, Collection, or Map. – VGR Mar 10 '23 at 04:22

2 Answers2

2

I think happy-songs comment and link to a solution is the right direction. You'll want something like this to pass your test.

Optional.ofNullable(x).map(Object::toString).map(String::toLowerCase).orElse(null);
kparkinson
  • 48
  • 3
0

Thank you @happy-song and @kparkinson. The map helped me get to the right direction. For context these maps can be chained just like any other map and that's what has to be done if you want to call

      @Test
       public void optionalsWorkingAsExpected() {
        Number x = null;
        String b = "hi there";

        var opt = Optional.ofNullable(x)
                .map(y -> y.toString())
                .map(str -> str.toLowerCase())
                .map(lower -> lower.toUpperCase())
                .orElse(null);

        assertThat(opt).isNull();

        var opt2 = Optional.ofNullable(b)
                .map(y -> y.toString())
                .map(str -> str.toLowerCase())
                .map(lower -> lower.toUpperCase())
                .orElse(null);
        assertThat(opt2).isEqualTo("HI THERE");

    }
codernoob8
  • 434
  • 1
  • 9
  • 24