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);
Answer from kparkinson on Stack OverflowTired of Null Pointer Exceptions? Consider Using Java SE 8's Optional!
Using Optionals in Java 11 to avoid null pointer exceptions using functional chaining - Stack Overflow
option type - Java optional null pointer exception - Stack Overflow
java - Optional of nullable on something giving NullPointerException - Stack Overflow
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);
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");
}
Use Optional.ofNullable if you are unsure whether you have a value or not, but you do not want a NullPointerException to be thrown.
Use Optional.of if you know you have a non-null-value or if it's ok for you if a NullPointerException is thrown otherwise.
Regarding the rest of your question: why null or Optional you may find the following question useful: Optional vs. null. What is the purpose of Optional in Java 8?
Your question may also be related to: Why use Optional.of over Optional.ofNullable?
Optional does not prevent from throwing an NPE, It makes it very easy to avoid, but you have to do your part, for example, I would refactor your code to something like this.
public void doSomethingA(String para) {
Optional<String> optName = Optional.ofNullable(para);
String name = optName.orElse("Unknown");
//At his point, you are completely sure that name is even given name or "Unknown"
//and can do wherever you want without being afraid of throwing a NPE
}
You can use other optional Method like:
optName.orElseThrow() to throw and error if your param is null, optName.orElseGet(() -> { return "Unknown" ;}); practically does the same than the example but you can add more logic to get the default value, or many other methods.