创建通用异常包装器的最佳方法是什么?
What is the best way to create a general Exception wrapper?
是否可以有一个像这样的通用异常包装器?
public Function<?, Optional<?>> ExceptionWrapper = (? input) -> {
try {
return Optional.of(someAction(input));
} catch (Exception e) {
logger.warn(e.getMessage());
}
return Optional.empty();
};
这些?
可以有不同的类型,类似于TS中的Any
。
目的是不重复相同的代码。
这可能只是一种不好的做法。
你可以使用这样的方法:
public static <T> Optional<T> wrappException(SupplierWithException<T> supplierThatThrowsException) {
try {
return Optional.of(supplierThatThrowsException.get());
}
catch (Exception e) {
//logger.warn(e.getMessage()); //TODO add a real logger here
System.err.println("logger warning: " + e.getMessage());
}
return Optional.empty();
};
这个方法获取一个SupplierWithException<T>
作为参数,然后执行。因此,您需要像这样创建功能接口 SupplierWithException<T>
:
@FunctionalInterface
public interface SupplierWithException<T> {
public T get() throws Exception;
}
现在可以像这样使用该方法(假设该方法在 class ExceptionWrapperUtil 中定义):
public static void main(String[] args) {
Optional<Integer> result1 = ExceptionWrapperUtil.wrappException(//
//create a SupplierWithException object (as lambda expression, because it's a functional interface)
//when the get() method is called (within the wrappException method) the calculation is started
() -> {
return doCalculations(true);//will throw an exception that is logged
});
Optional<Integer> result2 = ExceptionWrapperUtil.wrappException(() -> {
return doCalculations(false);//will succeed without an exception
});
System.out.println("result1 present: " + result1.isPresent());
System.out.println("result2 present: " + result2.isPresent());
System.out.println("result2: " + result2.get());
}
public static int doCalculations(boolean throwException) {
boolean failed = throwException;//test throwing an exception
//TODO do some calculations...
int theAnswer = 42;
if (failed) {
throw new IllegalStateException("calculations failed");
}
return theAnswer;
}
测试生成以下输出:
logger warning: calculations failed
result1 present: false
result2 present: true
result2: 42
完整示例代码
import java.util.Optional;
public class ExceptionWrapperUtil {
public static <T> Optional<T> wrappException(SupplierWithException<T> supplierThatThrowsException) {
try {
return Optional.of(supplierThatThrowsException.get());
}
catch (Exception e) {
//logger.warn(e.getMessage()); //TODO add a real logger here
System.err.println("logger warning: " + e.getMessage());
}
return Optional.empty();
};
@FunctionalInterface
public interface SupplierWithException<T> {
public T get() throws Exception;
}
public static void main(String[] args) {
Optional<Integer> result1 = ExceptionWrapperUtil.wrappException(//
//create a SupplierWithException object (as lambda expression, because it's a functional interface)
//when the get() method is called (within the wrappException method) the calculation is started
() -> {
return doCalculations(true);//will throw an exception that is logged
});
Optional<Integer> result2 = ExceptionWrapperUtil.wrappException(() -> {
return doCalculations(false);//will succeed without an exception
});
System.out.println("result1 present: " + result1.isPresent());
System.out.println("result2 present: " + result2.isPresent());
System.out.println("result2: " + result2.get());
}
public static int doCalculations(boolean throwException) {
boolean failed = throwException;//test throwing an exception
//TODO do some calculations...
int theAnswer = 42;
if (failed) {
throw new IllegalStateException("calculations failed");
}
return theAnswer;
}
}
您可以对@Tobias 提供的答案进行一些改进。
在问题中,我可以看到你想要传递一些通用类型的输入(假设 T
)并期望和 Optional<R>
类型。
这是新的功能界面,
@FunctionalInterface
public interface FunctionException<T, R> {
public R apply(T t) throws Exception;
}
然后是新的期望包装器,
public <T,R> Optional<R> wrapException(Function<T, R> function, T t) {
try { return Optional.of(function.apply(t)); }
catch (Exception e) {
System.out.println(e.getLocalizedMessage());
// todo: add logger
}
return Optional.empty();
};
您可以将具有以下签名的任何方法传递给 wrapException
方法。
R yourMethod(T t) throws Exception
这是一个例子,
public boolean someMethod(int in) throws IOException {
// your business logic
// my business logic
if (in == 4) throw new IOException("Some exception");
return in == 3;
};
你可以这样调用wrapException
Optional<Boolean> a = wrapException(YourClass::someMethod, 2);
Optional<Boolean> b = wrapException(YourClass::someMethod, 4);
是否可以有一个像这样的通用异常包装器?
public Function<?, Optional<?>> ExceptionWrapper = (? input) -> {
try {
return Optional.of(someAction(input));
} catch (Exception e) {
logger.warn(e.getMessage());
}
return Optional.empty();
};
这些?
可以有不同的类型,类似于TS中的Any
。
目的是不重复相同的代码。
这可能只是一种不好的做法。
你可以使用这样的方法:
public static <T> Optional<T> wrappException(SupplierWithException<T> supplierThatThrowsException) {
try {
return Optional.of(supplierThatThrowsException.get());
}
catch (Exception e) {
//logger.warn(e.getMessage()); //TODO add a real logger here
System.err.println("logger warning: " + e.getMessage());
}
return Optional.empty();
};
这个方法获取一个SupplierWithException<T>
作为参数,然后执行。因此,您需要像这样创建功能接口 SupplierWithException<T>
:
@FunctionalInterface
public interface SupplierWithException<T> {
public T get() throws Exception;
}
现在可以像这样使用该方法(假设该方法在 class ExceptionWrapperUtil 中定义):
public static void main(String[] args) {
Optional<Integer> result1 = ExceptionWrapperUtil.wrappException(//
//create a SupplierWithException object (as lambda expression, because it's a functional interface)
//when the get() method is called (within the wrappException method) the calculation is started
() -> {
return doCalculations(true);//will throw an exception that is logged
});
Optional<Integer> result2 = ExceptionWrapperUtil.wrappException(() -> {
return doCalculations(false);//will succeed without an exception
});
System.out.println("result1 present: " + result1.isPresent());
System.out.println("result2 present: " + result2.isPresent());
System.out.println("result2: " + result2.get());
}
public static int doCalculations(boolean throwException) {
boolean failed = throwException;//test throwing an exception
//TODO do some calculations...
int theAnswer = 42;
if (failed) {
throw new IllegalStateException("calculations failed");
}
return theAnswer;
}
测试生成以下输出:
logger warning: calculations failed
result1 present: false
result2 present: true
result2: 42
完整示例代码
import java.util.Optional;
public class ExceptionWrapperUtil {
public static <T> Optional<T> wrappException(SupplierWithException<T> supplierThatThrowsException) {
try {
return Optional.of(supplierThatThrowsException.get());
}
catch (Exception e) {
//logger.warn(e.getMessage()); //TODO add a real logger here
System.err.println("logger warning: " + e.getMessage());
}
return Optional.empty();
};
@FunctionalInterface
public interface SupplierWithException<T> {
public T get() throws Exception;
}
public static void main(String[] args) {
Optional<Integer> result1 = ExceptionWrapperUtil.wrappException(//
//create a SupplierWithException object (as lambda expression, because it's a functional interface)
//when the get() method is called (within the wrappException method) the calculation is started
() -> {
return doCalculations(true);//will throw an exception that is logged
});
Optional<Integer> result2 = ExceptionWrapperUtil.wrappException(() -> {
return doCalculations(false);//will succeed without an exception
});
System.out.println("result1 present: " + result1.isPresent());
System.out.println("result2 present: " + result2.isPresent());
System.out.println("result2: " + result2.get());
}
public static int doCalculations(boolean throwException) {
boolean failed = throwException;//test throwing an exception
//TODO do some calculations...
int theAnswer = 42;
if (failed) {
throw new IllegalStateException("calculations failed");
}
return theAnswer;
}
}
您可以对@Tobias 提供的答案进行一些改进。
在问题中,我可以看到你想要传递一些通用类型的输入(假设 T
)并期望和 Optional<R>
类型。
这是新的功能界面,
@FunctionalInterface
public interface FunctionException<T, R> {
public R apply(T t) throws Exception;
}
然后是新的期望包装器,
public <T,R> Optional<R> wrapException(Function<T, R> function, T t) {
try { return Optional.of(function.apply(t)); }
catch (Exception e) {
System.out.println(e.getLocalizedMessage());
// todo: add logger
}
return Optional.empty();
};
您可以将具有以下签名的任何方法传递给 wrapException
方法。
R yourMethod(T t) throws Exception
这是一个例子,
public boolean someMethod(int in) throws IOException {
// your business logic
// my business logic
if (in == 4) throw new IOException("Some exception");
return in == 3;
};
你可以这样调用wrapException
Optional<Boolean> a = wrapException(YourClass::someMethod, 2);
Optional<Boolean> b = wrapException(YourClass::someMethod, 4);