我试图编写一个接收错误并返回相同的方法,但在消息末尾添加了感叹号,但是存在一个问题,即java中的错误是不可变的,并且由于泛型的限制无法使用新T(e,message)创建新的错误实例:
public static <T extends Throwable> T withExclamationMark(T error) {
return new T(error.getMessage() + "!", error);
}
有没有需要反射等的简单解决方案?
你可以用BiFunction
做到这一点:
public static <T extends Throwable> T withExclamationMark(
T error,
BiFunction<String, T, T> factory) {
return factory.apply(error.getMessage() + "!", error);
}
然后,您可以使用以下方法:
RuntimeException original = new RuntimeException("Message");
RuntimeException decorated = withExclamationMark(original, RuntimeException::new);
System.out.println(decorated.getMessage()); // Message!
public static void main(String[] args) throws Exception {
Throwable t = new Throwable("my message");
Throwable t2 = withExclamationMark(t);
t2.printStackTrace();
}
public static <T extends Throwable> T withExclamationMark(T error)
throws Exception {
Constructor c = error.getClass().getConstructor(String.class,
Throwable.class);
return (T) c.newInstance(error.getMessage() + "!", error);
}
如果您想不惜一切代价避免反思,您将不得不为此付出代价。所提出的解决方案将牺牲精度w.r.t。 Throwable
的类型。要在消息中附加内容,我们将通过部署构造函数Throwable
将给定的Exception
包装在Exception(String, Throwable)
中
public static <T extends Throwable> Exception withExclamationMark(T t) {
return new Excpetion(t.getMessage() + "!", t);
}
正如我已经提到的,这个方法只返回类Exception
的实例,因此当你尝试catch
那些Exception
s时,你必须检查cause
:
try {
...
} catch (Exception e) { // let's assume you would normally catch an IOException here
Exception cause = e.getCause();
if ((cause != null) && (cause instanceof IOException) {
IOException ioEx = ((IOExcpetion) cause);
// handle excpetion
} else {
throw e; // or System.exit(42) or halt and catch fire or ...
}
}
有关部署反射的解决方案,请参阅@sanit's answer。也许两个答案的组合可以带来令人满意的解决方案。