【问题标题】:Non null string wrapper非空字符串包装器
【发布时间】:2019-07-24 23:58:13
【问题描述】:

我的 java 代码中有一种情况,我必须对字符串参数进行大量空值检查:

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

我知道,Google Guava 有特殊功能,所以可以这样写代码:

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

但我喜欢纯 OOP,所以我尽量减少在我的代码中使用静态方法。在某些库或框架中是否有标准 String 的特殊装饰器/包装器类,可以封装这种行为?比如:

class StrictString {

        private final String origin;

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

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

非常感谢您的帮助。

【问题讨论】:

  • @TimBiegeleisen 不完全是。这个问题更多的是关于语法。我确切地询问了装饰器/包装器类。
  • @maximusKon 我还想补充一点,在我看来,使用包装类意味着在任何地方都依赖它。就像病毒一样,到处蔓延。我不会走这条路。风险很高
  • @LppEdd 好吧,在这种情况下,标准的 java String 类是同一个病毒。这就是为什么我不想自己编写它,而是在 Apache Commons 或 Google Guava 等框架中找到实现。
  • 使用 Optional 的更好替代方法是 Objects.toString。如Objects.toString(personPhone.getName(), "")。 Optional 不应用作冗长的 if/else。

标签: java oop


【解决方案1】:

如果你不喜欢写很多代码(像我一样!),如果你不喜欢每次都用方法调用包装对象,我建议你看看Manifold 项目,尤其是扩展类功能 (documentation)。

基本上,它基于字节码操作(可选 - 在运行时)和注释处理(在编译时),它允许您编写自定义扩展方法(例如,与 Kotlin 中相同)。

使用Manifold 的一种可能方法是

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

// Or even
name.orEmpty();

恕我直言,太棒了
我已经在我的个人项目中成功使用了Manifold,我推荐它。

【讨论】:

  • 扩展方法看起来不错,但老实说,它们是相同的静态方法,但带有语法糖。我认为他们隐藏了问题,但没有解决问题。但是谢谢你的参考,我会仔细研究这个项目。
  • @maximusKon 不幸的是,Java 没有提供任何本地方法来解决这个问题。经过数月的反复试验,这是我找到的唯一可接受的解决方案。不过,我完全理解你的疑虑。
  • @maximusKon 以及如何逐步切换到 Kotlin?你只能用它编写新代码。
  • 是的,我同意你的看法。但是我目前的项目是在 Java 上的,所以我有它的工作。
  • @maximusKon 我想你在企业/金融领域工作。所以我知道引入新的依赖项并不是经常发生的事情。
【解决方案2】:

我不知道这样的装饰器类。
您可以使用具有getOrDefault()MapProperties,但这确实违反直觉。
另一种选择是Function 或这里是UnaryOperator

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

但老实说,我会坚持使用辅助方法或您在问题中介绍的自定义包装器。
在某些情况下,引入特定的类确实很合适。如果您想在没有static 的情况下这样做,似乎就是这种情况。

【讨论】:

  • 有趣的想法,但我宁愿重用别人的实现,然后自己写。
猜你喜欢
  • 2017-06-12
  • 1970-01-01
  • 2021-06-12
  • 2018-07-04
  • 1970-01-01
  • 2011-09-21
  • 1970-01-01
  • 2013-04-29
  • 2015-09-13
相关资源
最近更新 更多