Java可选方法参数?

时间:2015-03-14 15:51:40

标签: java java-8 guava optional

我正在阅读这篇关于使用Optionals进行方法论证的文章,而且似乎一致认为永远不会将它们用于此目的。

Guava Optional as method argument for optional parameters

但是API方面(不是应用程序方面)根本没有这个规则的例外吗?我无法想出一种更清晰的方法来处理某些情况,尤其是在初始化情况下,可能会或可能不会使用参数参数。

利用这个可以构建的I&#m; m建筑物,提供我们企业使用的四个数据库连接。前三个不需要参数,因为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;
    }

}

1 个答案:

答案 0 :(得分:4)

首先,如果您正在使用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(番石榴)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();
}