java - 可以使用Optional作为捕获ConversionException的替代方法

标签 java monads option-type

如何重构以下读取属性文件的代码,使其根据读取的值返回 int、double 或 String?

    public static <T> T readFromConfig(String keyName) {
    PropertiesConfiguration config = new PropertiesConfiguration();
    String propertiesFilePath = "src/main/resources/application.properties";
    try {
        config.load(propertiesFilePath);
        try {
            Integer value = config.getInt(keyName);
            return (T) value;
        } catch (ConversionException notInteger) {
            try {
                Double value = config.getDouble(keyName);
                return (T) value;
            } catch (ConversionException notDouble) {
                return (T) config.getString(keyName);
            }
        }
    } catch (ConfigurationException e) {
        logger.warn("Could not parse " + propertiesFilePath);
        return (T) "";
    }
}

最佳答案

正如作者自己所想:Optional<>在这里不是一个选项,因为,正如另一个答案所示:它将导致返回 Optional<Object>这提供了更少的类型信息。

但老实说,从干净的代码角度来看,即使是

public static <T> T readFromConfig(String keyName) {

有点有缺陷。这个方法能买到什么? 什么都没有。因为调用者说:我希望返回一个 Integer,但你推回了一个 Double 甚至 String。你看,编译器被告知“该方法应该返回 Integer,或 Double,...”,然后它看到:“是的,可能”。但这与运行时发生的事情完全脱钩。

如果你去:

Integer intVal = readFromConfig("keyPointingToDoubleValue");

编译器不会提示。因为它看到:您想要一个 Integer;嘿,该方法可以返回一个整数。

运行时?当检索到的值不是 Integer 时,将返回 Double 或 String。不知道这里会发生什么(类转换异常,或者可能是一些堆栈冲突)。但它不应该在运行时工作。

所以,真正的解决方案是这样的:

要么你有多种方法,例如:

public static Integer readIntegerFromConfig(String keyName) throws SomeException ...
public static Integer readIntegerFromConfig(String keyName, Integer Default) throws SomeException ...

或者也许:

public static Object readFromConfig(String keyName) {

public static <T> T readFromConfig(String keyName, T default)

换句话说:您需要一个 API,允许用户真正说出他们想要的内容,并始终为他们提供他们想要的内容。或者您完全避免该级别上的不同类型,并返回字符串,并让客户端代码进行转换。

如前所述,您当前的方法:不会为您带来任何好处,但代价是误导性的、复杂的 API。

关于java - 可以使用Optional作为捕获ConversionException的替代方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52177833/

相关文章:

java - 对数组的每个元素进行并行递归函数调用(使用 ForkJoinPool)

java - Spring-restdocs:如何制作参数、路径和响应字段代码块

java - Elassandra - 错误 : Could not find or load main class org. apache.cassandra.stress.Stress

haskell - 为什么 Applicative 应该是 Monad 的父类(super class)?

swift - 可选用 ?在 swift

java - 过滤特定cookie的cookie数组并获取Java中特定cookie的值

java - 如何将数据传递到外键,在传递数据时我使用 postman 得到空值?

Haskell:运行两个单子(monad),保留第一个的结果

Haskell 函数由两个二元函数组成?

ios - 无法检查我的变量是否为零 SWIFT