繁体   English   中英

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

[英]Can Optional be used to as alternative to catch ConversionException

如何重构以下读取属性文件的代码,以便根据读取的值返回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) "";
    }
}

我也可以建议您,这也明显违反了单一职责原则(SRP),因为它试图转换为三种不同的类型,对于更简洁的代码应避免使用:

public static Optional<Object> readFromConfig(String keyName) {
    PropertiesConfiguration config = new PropertiesConfiguration();
    String propertiesFilePath = "src/main/resources/opf.properties";
    try {
        config.load(propertiesFilePath);

        return Stream.<Supplier<Optional>>of(
                () -> Optional.of(config.getInt(keyName)),
                () -> Optional.of(config.getDouble(keyName)),
                () -> Optional.of(config.getString(keyName)))
                .map(Supplier::get)
                .filter(Optional::isPresent)
                .map(Optional::get)
                .findFirst();

    } catch (Exception e) {
        return Optional.empty();
    }
}

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

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

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

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

如果你走的话:

Integer intVal = readFromConfig("keyPointingToDoubleValue");

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

在运行时? 当检索到的值不是整数时,将返回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允许其用户真正说出他们想要的东西,并始终为他们提供他们想要的东西。 或者,您完全避免在该级别使用不同的类型,并返回String,并让客户端代码进行转换。

如您所说,您当前的方法:以误导,复杂的API为代价,不会为您带来任何收益。

所以,这就是讨论的终点。 问题“可以使用Optional作为捕获ConversionException的替代方法吗?”的答案。 NO

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM