2

I have a situation in my java code, where I must to do a lot of null checks for string parameters:

someService.someUpdateFunc(Optional.ofNullable(personPhone.getName()).orElse(""),
                           Optional.ofNullable(personPhone.getNumber()).orElse(""),
                           Optional.ofNullable(personPhone.getDescription()).orElse("")
        );

I know, that there is the special function in Google Guava, so it's possible to write code like that:

someService.someUpdateFunc(nullToEmpty(personPhone.getName()),
                           nullToEmpty(personPhone.getNumber()),
                           nullToEmpty(personPhone.getDescription())
            );

But I like pure OOP, so that I try to reduce using of static methods in my code. Is there a special decorator/wrapper class for standard String in some library or framework, which could incapsulate this behavior? Something like:

class StrictString {

        private final String origin;

        public StrictString(String origin) {
            this.origin = origin;
        }

        public String asString() {
            return Optional.ofNullable(origin).orElse("");
        }
}

Thanks a lot for helping.

maximusKon
  • 136
  • 9
  • Possible duplicate of: https://stackoverflow.com/questions/5223044/is-there-a-java-equivalent-to-null-coalescing-operator-in-c – Tim Biegeleisen Mar 03 '19 at 15:14
  • @TimBiegeleisen not quite. This question is more about syntax. I asked exactly about decorator/wrapper class. – maximusKon Mar 03 '19 at 17:13
  • @maximusKon I would also like to add that in my opinion using a wrapper class means depending on it everywhere. It's like a virus, it will expand everywhere. I wouldn't take this route. The risk is very high – LppEdd Mar 03 '19 at 17:23
  • @LppEdd well, standard java String class is the same virus in this case. And that's why I don't want to write it by myself, but find realization in some framework like Apache Commons or Google Guava. – maximusKon Mar 03 '19 at 18:05
  • @maximusKon I've never seen such a wrapper class around. I think your problem can be solved in other ways. I mean, if you want to state a parameter cannot be null you can use the NotNull annotation (e.g. from JetBrains). Than it's up to the team to respect the contract. If you apply those annotations from the beginning you won't have this problem – LppEdd Mar 03 '19 at 18:10
  • 1
    A better alternative to using Optional is [Objects.toString](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/Objects.html#toString%28java.lang.Object,java.lang.String%29). As in, `Objects.toString(personPhone.getName(), "")`. Optional should not be used as a long-winded if/else. – VGR Mar 03 '19 at 23:09

2 Answers2

1

If you don't like writing a lot of code (like me!), and if you don't like wrapping objects with method calls every time, I suggest you take a look at the Manifold project, especially the extension classes capability (documentation).

Basically, it is based on bytecode-manipulation (optional - at run-time) and annotation-processing (at compile-time), and it lets you write custom extension methods (e.g. the same as in Kotlin).

A possible approach you might arrive to using Manifold is

final String name = ...
name.orElse("");

// Or even
name.orEmpty();

Which imho, is awesome.
I've successfully used Manifold in my personal projects and I recommend it.

LppEdd
  • 20,274
  • 11
  • 84
  • 139
  • Extension methods look good, but honestly they are the same static methods, but with syntax sugar. They hide problems, but not solve them, I think. But thank you for reference, I'll look closer on this project. – maximusKon Mar 03 '19 at 17:35
  • @maximusKon unfortunately Java doesn't provide any native way to solve this problem. After many months of trial and error this is the only acceptable solution I found. I perfectly understand your doubts, however. – LppEdd Mar 03 '19 at 17:42
  • @maximusKon and what about progressively switching to Kotlin? You can write new code only with it. – LppEdd Mar 03 '19 at 17:45
  • yes, I agree with you. But my current project is on Java, so I have work with it. – maximusKon Mar 03 '19 at 17:59
  • @maximusKon I suppose you work on the enterprise/finance field. So I understand that introducing new dependencies is not something that happens a lot. – LppEdd Mar 03 '19 at 18:00
1

I don't know such a decorator class.
You could use a Map or Properties that has getOrDefault() but it is really counter intuitive.
An alternative would be a Function or here an UnaryOperator.

UnaryOperator<String> orToEmptyFn = p -> p == null ? "" : p;
someService.someUpdateFunc(orToEmptyFn.apply(personPhone.getName()),
                           orToEmptyFn.apply(personPhone.getNumber()),
                           orToEmptyFn.apply(personPhone.getDescription())
            );  

But honestly I would stick to a helper method or the custom wrapper you introduced in your question.
In some cases, introducing specific classes is really suitable. Here it seems the case if you want to do that without static.

davidxxx
  • 125,838
  • 23
  • 214
  • 215