如何重构以下读取属性文件的代码,以便根据读取的值返回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) "";
}
}
答案 0 :(得分:1)
在这里,我也可以建议您,这也明显违反了“单一职责原则”(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();
}
}
答案 1 :(得分:1)
正如作者认为的那样: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为代价,您什么都不会买。
答案 2 :(得分:0)
所以,这就是讨论的终点。 问题“可以使用Optional作为捕获ConversionException的替代方法吗?”的答案。是否