使用java供应商接口创建条件对象

我有一个方法如下:

void updateObject(ObjOne obj, SomeClass data) {
    if(obj != null) {
        obj.doSomething(data);
    }
}

updateObject多次调用,避免空检查在每一个地方,我想避免以下的:

// directly invoke doSomething conditionally.
if(obj != null) {
    SomeClass data = getData();
    obj.doSomething(data);
}

由于data仅在obj非空时使用,我想到了如下重构代码:

void updateObject(ObjOne obj, Supplier<SomeClass> data) {
    if(obj != null) {
        obj.doSomething(data.get());
    }
}

这将SomeClass仅在需要时创建一个对象,而是创建一个Supplier类型的对象。

上述方法使用Supplier更好吗?

回答

性能取决于构建SomeClass实例的成本,换句话说,只创建一个而不创建Supplier一个SomeClass实例可以节省什么,以及不创建SomeClass实例的可能性。如果SomeClass在大多数情况下无论如何都创建了实例,显然您不能通过额外创建一个Supplier.

如果您在不知道费用和可能性的情况下设计 API,您可以提供这两种方法并让调用者决定使用哪种方法。这是一个既定的模式,例如

  • Objects.requireNonNull?(T obj, String message) 对比
  • Objects.requireNonNull?(T obj, Supplier<String> messageSupplier)

或者

  • Objects.requireNonNullElse?(T obj, T defaultObj) 对比
  • Objects.requireNonNullElseGet?(T obj, Supplier<? extends T> supplier)

或者

  • Optional.orElse?(T other) 对比
  • Optional.orElseGet?(Supplier<? extends T> supplier)

或者

  • log?(System.Logger.Level level, String msg) 对比
  • log?(System.Logger.Level level, Supplier<String> msgSupplier)
  • @Eugene sounds like an issue that can be solved with code transformation. `logger.method(/*string concatenation*/)` gets compiled (JDK 9+) to *push logger, push arguments*, `invokedynamic` (string concatenation), `invoke… method`. The transformator only has to replace the two invocations with a single `invokedynamic` with a custom bootstrap method that consumes *logger* and *arguments*. The custom bootstrap method only needs to get a handle to the original method and prepend the condition check.

以上是使用java供应商接口创建条件对象的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>