假设我必须读取一个文件,然后从中构造一个Java对象。
PersonData p = new PersonData();
p.setName(readTokenAsString());
p.setAge(AgeConverter.createFromDateOfBirth(readTokenAsString())); // this throws a checked exception if the date of birth is mal-formed.
//... a list of methods that throws exception as AgeConverter
我想要的行为:如果一个属性有问题,请忽略它并继续处理其他属性。
我能想到的解决方案:
try {
p.setAge1(...);
} catch (Exception e) {
//log and ignore
}
try {
p.setAge2(...);
} catch (Exception e) {
//log and ignore
}
//repeat for each attribute
问题:
是否有更好的方法来避免重复?功能风格也许吗?
a)如果无法修改PersonData
类,最好的方法是什么。
b)如果我可以重写PersonData
类,那是最好的方法。
答案 0 :(得分:2)
鉴于您当前的声明,我将按照以下说明进行操作。
定义一个@FunctionalInterface
,您可以将其I / O逻辑传递给该对象:
@FunctionalInterface
public interface CheckedSupplier<T> {
T getValue() throws Exception;
}
定义使用@FunctionaInterface
的实用程序方法:
public static final <T> T getValueWithDefault(CheckedSupplier<T> supplier, T defaultValue) {
try {
return supplier.getValue();
} catch (Exception e){
return defaultValue;
}
}
使用实用程序方法如下:
PersonData p = new PersonData();
p.setName(getValueWithDefault(() -> readTokenAsString(), "default"));
p.setAge(getValueWithDefault(() -> AgeConverter.createFromDateOfBirth(readTokenAsString()), 0));
无论您是否要修改PersonData
类,无论天气如何,这都可以解决问题。
答案 1 :(得分:1)
如果您使用Java 8,则可以执行以下操作。使用一种抛出Exception
public interface MyConsumer<T> {
public void process(T t) throws Exception;
}
并创建一个static
方法来使用该接口
public static <T> void setAndLogException(T value, MyConsumer<T> consumer) {
try {
consumer.process(value);
} catch (Exception e) {
// log exception
}
}
然后像setAndLogException(AgeConverter.createFromDateOfBirth(readTokenAsString()), p::setAge);
答案 2 :(得分:0)
您还可以使用以下提供的解决方案:https://stackoverflow.com/a/28659553/6648303
此解决方案在编译阶段不会抱怨已检查的异常。 会是这样的:
public static void ignoringExc(RunnableExc r) {
try { r.run(); } catch (Exception e) { }
}
@FunctionalInterface public interface RunnableExc { void run() throws Exception; }
然后:
PersonData p = new PersonData();
ignoringExc(() -> p.setName(readTokenAsString()));
...