我想问您关于如何最好地管理这种情况的建议:
public Unit createUnit(final int unitLevel) {
final List<String> widgetClassNames = getUnitsClasses();
try {
return (Unit) Class.forName(widgetClassNames.get(unitLevel))
.getConstructor(Player.class).newInstance(getOwner().get());
} catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException
| NoSuchMethodException | SecurityException | ClassNotFoundException e) {
e.printStackTrace();
}
return null;
}
此方法创建一个单元并返回它,但我不喜欢在发生异常的情况下我返回return null的事实。 我该怎么解决?
谢谢!
答案 0 :(得分:4)
创建一个合适的新Exception
,它可以管理自定义数据,例如输入unitLevel
的值。
public class UnitCreationException extends Exception {
...
// Package-private constructor.
// Don't expose too much to the outer world
UnitCreationException(
final String message,
final int unitLevel,
final Throwable cause) { ... }
}
就地捕获Exception
,记录您认为可能是有用的信息,这些信息只能在那时才能访问
public Unit createUnit(final int unitLevel) throws UnitCreationException {
final List<String> widgetClassNames = getUnitsClasses();
try {
return (Unit) Class.forName(widgetClassNames.get(unitLevel))
.getConstructor(Player.class)
.newInstance(getOwner().get());
} catch (InstantiationException
| IllegalAccessException
| IllegalArgumentException
| InvocationTargetException
| NoSuchMethodException
| SecurityException
| ClassNotFoundException e) {
// Do not log the Exception stack-trace here, you'll do that
// at a hihger level
logger.error("Error message");
// Re-throw your custom and more meaningful Exception
throw new UnitCreationException("Error message", unitLevel, e);
}
}
在更高级别上,您将被迫抓住UnitCreationException
try {
final Unit unit = createUnit(10);
} catch (final UnitCreationException e) {
// Here you can log the Exception stack-trace
logger.error("Error message", e);
// Do something with the information contained in the custom Exception
final int erroredUnitLevel = e.getUnitLevel();
...
}
一直以来,关于检查的Exception
s vs RuntimeException
s一直存在争议。我觉得这是一个经过检查的好用例,尤其是如果它是可以供多个客户端使用的库的一部分时。
您希望能够从这样的错误中以某种方式恢复,而不必停止整个应用程序(也许使用重试逻辑)。
我目睹了开发人员使用Optional<T>
作为返回类型,只是为了避免使用null
。这会产生适得其反的作用,因为您丢失了错误的实际原因,并且无法对它自己的分支(catch
分支)中的错误做出反应
最终,Java为您提供了一种自定义Exception
的方法,因此请使用此功能。
答案 1 :(得分:0)
最重要的是,您的呼叫者会获得createUnit()
呼叫失败的信息。您已经说过null
是一个糟糕的选择,我完全同意。
最好的方法是向呼叫者抛出一个异常,但是哪一个呢?
原来的一个?
还是新创建的一个?
我们应该考虑哪些方面?
因此,我看到的将较低级别的异常包装在较高级别的异常中的唯一原因是,如果要添加对日志记录有用的上下文信息(或者某些固定方法签名迫使您转换原始异常)