【问题标题】:Java Optional for method argument?方法参数的Java可选?
【发布时间】:2015-05-17 00:52:52
【问题描述】:

我正在阅读这篇关于将 Optionals 用于方法参数的帖子,而共识似乎是永远不要将它们用于此目的。

Guava Optional as method argument for optional parameters

但是在 API 端(而不是应用端)是否存在此规则的例外情况?我想不出一种更简洁的方法来处理某些情况,尤其是在可能使用或不使用参数参数的初始化情况下。

以我正在构建的这个枚举为例,它提供了我们的业务使用的四个数据库连接。前三个不需要参数,因为DbManager 工厂已经拥有它需要的配置信息。但是 SQLite 连接需要一个正在使用的 SQLite 数据库的 URL。因此,我需要将我的Supplier 变成Function<Optional<String>,DatabaseConnection>

使用Optional 作为方法参数是否合法?如果不是,我怎样才能使这个可枚举?

private static enum DbConnectionSupplier {
    ORACLE(optArg -> DbManager.getOracleConnection()),
    MYSQL(optArg -> DbManager.getMySQLConnection()),
    TERADATA(optArg -> DbManager.getTeradataConnection()),
    SQLITE(optArg -> DbManager.getSQLiteConnection(optArg.get()));

    private final Function<Optional<String>, DatabaseConnection> supplier;
    private DbConnectionSupplier(Function<Optional<String>, DatabaseConnection> supplier) { 
        this.supplier = supplier;
    }

}

【问题讨论】:

标签: java java-8 guava optional


【解决方案1】:

首先,如果您使用的是 lambda 表达式,那么您正在使用 Java 8 进行编译,您可以使用 java.util.Optional,而不是 Guava。

我猜你有以下方法:

DatabaseConnection getConnection(String arg) {
   return supplier.apply(Optional.of(arg));
}

DatabaseConnection getConnection() {
   return supplier.apply(Optional.empty());
}

现在,它不能保护您免受拨打TERADATA.getConnection("BAR") 的人的侵害。另一方面,SQLITE.getConnection() 将失败,NoSuchElementException(Java8) 或IllegalStateException(Guava) 在optArg.get(),因为可选是空的。 从那个异常中并不清楚getConnection 中应该有一个参数(好吧,可能很清楚,但是调用Function.apply 会“污染”堆栈跟踪)

以下实现避免使用Optional,并清楚地表明是否需要某个参数。

TERADATA(()-> DbManager.getTeradataConnection()),
SQLITE(arg -> DbManager.getSQLiteConnection(arg)),
FOO(()-> DbManager.getFooConnection(),
    arg->DbManager.getFooConnection(arg));
//Foo supports both styles: with and without a parameter

private final Supplier<DatabaseConnection> supplier;
private final Function<String, DatabaseConnection> function;

private DbConnectionSupplier(Supplier<DatabaseConnection> supplier) { 
    this.supplier = supplier;
    this.function = null;
}    

private DbConnectionSupplier(Function<String, DatabaseConnection> function) { 
    this.function = function;
    this.supplier = null;
}    `

private DbConnectionSupplier(
    Supplier<DatabaseConnection> supplier,
    Function<String, DatabaseConnection> function) { 
    this.function = function;
    this.supplier = supplier;
}    

public DatabaseConnection getConnection(String arg) {
   if (function==null) throw ...
   return function.apply(arg);
}

public DatabaseConnection getConnection() {
   if (supplier==null) throw ...
   return supplier.get();
}

【讨论】:

  • 供应商必须拥有完成其预期工作所需的所有信息。不需要单独的function
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-08
  • 1970-01-01
  • 2012-06-19
  • 1970-01-01
  • 2023-02-15
  • 1970-01-01
相关资源
最近更新 更多