How to handle checked exceptions inside a functor object in Java
We use the http://jedi.codehaus.org libraries for working with collections and manipulating them in a functional way. We recently came across a problem when do开发者_如何学Pythoning something similar to the following:
public class Address {
//constructors and stuff
public KiloWatts electricityConsumed(Duration timePeriod) throw NoElectricitySupply {
.... does stuff but can throw checked exception
}
}
given we have a collection of addresses and we wanted to perform something on the UnitsOfElectricity associated with each address, how would you handle the thrown exception e.g.:
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?
}
}
});
}
How would you handle the exception?
As far as I can tell, you have 2 options:
- throw a runtime exception (and ignore it); or
- throw a runtime exception, using it to 'marshall' the checked exception past the interface boundary.
for (2), something like:
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();
}
}
why not return an Option<Kilowatts> from the functor so you can return None for the exceptional case? You can then flatten the List<Option<Kilowatts>> to List<Kilowatts> (there is a method on FunctionalPrimitives for that).
Alternatively, if you have control over the energyConsumed method which throws the Exception, replace the thrown Exception with are return type of Either<String, Kilowatts> (the String can contain an error message or something - I would need to see more to understand what to do there).
Using Either instead of exceptions enables composition, exceptions break composition completely.
If NoElectricitySupply
is logically equivalent to zero KiloWatts
, shouldn't you just return such object?
If they're not quite equivalent, you could create some sort of special NoKiloWatts
subclass and return an instance of such in the catch
block.
精彩评论