在Java中出现异常后继续执行的更好方法

时间:2018-11-06 03:50:15

标签: java orm exception-handling functional-programming

假设我必须读取一个文件,然后从中构造一个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类,那是最好的方法。

3 个答案:

答案 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()));
...