如何在Java中的functor对象中处理已检查的异常

时间:2010-10-15 13:49:33

标签: java exception functional-programming

我们使用http://jedi.codehaus.org库来处理集合并以功能方式对它们进行操作。我们最近在做类似以下的事情时遇到了一个问题:

public class Address {
    //constructors and stuff

    public KiloWatts electricityConsumed(Duration timePeriod) throw NoElectricitySupply {
        .... does stuff but can throw checked exception
    } 
}

鉴于我们有一组地址,我们想在与每个地址相关的UnitsOfElectricity上执行某些操作,您将如何处理抛出的异常,例如:

public KiloWatts totalEnergyConsumed(Address... addresses, final Duration timePeriod) {
     List<KiloWatts> energyConsumedPerAddress = FunctionalPrimitives.collect(addresses, new Functor<Address, KiloWatts>{
         public KiloWatts execute(Address address){
              try {
                  return address.energyConsumed(timePeriod);
              } catch (NoElectricitySupply e) {

                  //What do you do here?

              }
         }
     });
}

你会如何处理这个例外?

3 个答案:

答案 0 :(得分:3)

据我所知,你有两个选择:

  1. 抛出运行时异常(并忽略它);或
  2. 抛出运行时异常,使用它来“检查”经过接口边界的已检查异常。
  3. 对于(2),

    ,类似于:

    public KiloWatts totalEnergyConsumed(Address... addresses, final Duration timePeriod) {
        try {
            List<KiloWatts> energyConsumedPerAddress = FunctionalPrimitives.collect(addresses, new Functor<Address, KiloWatts>{
                public KiloWatts execute(Address address){
                    try {
                        return address.energyConsumed(timePeriod);
                    } catch (NoElectricitySupply e) {
                        throw new RuntimeException("internal marshalling exception", e);
                    }
               }
           });
        } catch(RuntimeException re) {
            throw e.getCause();
        }
    }
    

答案 1 :(得分:1)

如果NoElectricitySupply在逻辑上等于零KiloWatts,那么你不应该只返回这样的对象吗?

如果它们不完全等效,您可以创建某种特殊的NoKiloWatts子类,并在catch块中返回此类实例。

答案 2 :(得分:1)

为什么不从仿函数返回Option<Kilowatts>,以便在特殊情况下返回None?然后,您可以展平列表&lt; Option&lt; Kilowatts&gt;&gt;列出&lt; Kilowatts&gt; (在FunctionalPrimitives上有一个方法)。

或者,如果您可以控制抛出异常的energyConsumed方法,则将抛出的异常替换为返回类型Either<String, Kilowatts>(String可以包含错误消息或其他内容 - 我需要查看更多内容了解该做什么)。

使用Either代替异常会使合成,异常完全破坏合成。