假设我有一个类需要在其构造函数中进行一些初始化工作。没有理由相信它会失败,但如果确实如此,那么实例(可能是应用程序;让我们认为这些是两个独立的情况)将处于无法使用的状态,并且在该范围内没有真正的恢复希望(实例或全球)。
在Java中处理这种情况的推荐方法是什么?重新抛出异常,包含在运行时异常中,似乎是一种自然的方法,但对于为此目的使用哪种异常类型是否有任何建议或共识?
答案 0 :(得分:1)
如果构造函数中的某些内容抛出异常,您可以声明它自己抛出异常,也可以用更常见的异常包装它们(比如自己的InstantiateXxxxException)。
通常,您有多种类型的Throwable
具有不同的含义
我将它们分类如下:
答案 1 :(得分:0)
这取决于出了什么问题。我的意思是如果由于null值而失败,那么NullPointerexception,如果你遇到了不期望的状态,那么可能是IllegalStateException。
但我建议不要暴露构造函数只是有一个静态工厂方法,你可以命名,并可以优雅地处理这种情况。 e.g。
public class A{
private A() {}
private init() { .. }
public static A getNewInstance() { // may be parameters if you want
A a = new A();
a.init();
}
}
我刚刚举了一个init
的例子,但你也可以有其他的选择,重点是你可以使用静态方法来处理这些东西而不是构造函数,如果构造函数正在处理复杂的逻辑。
答案 2 :(得分:0)
如果在对象的构造函数中抛出异常,它与在方法调用中查找异常没什么不同,除了可以保证对象没有被构造
NewObject obj = null;
try {
obj = new NewObject() {
} catch (Throwable t) {
// obj is null.
}
是否可以从这样的异常中恢复很大程度上取决于抛出的异常。预计会检查异常,但偶尔会出现错误;通常他们是最容易恢复的。未经检查的异常涉及除以零之类的事情(必须捕获每个可能的抛出将是繁琐的)。错误是程序可能因正常JVM操作未保持的标准假设而失败的情况(如分配更多内存的能力)。
可以从某些JVM错误中恢复;但是,您希望从中恢复的错误以及恢复方法需要仔细规划。通常,人们会看到在处理内存不足的情况时尝试从JVM错误中恢复(后面是伪Java代码)
Runtime runtime = Runtime.getRuntime();
while (true) {
Cache myCache = new SomeCache();
try {
Message message = messages.getMessage();
if (!(cache.hasKey(message))) {
Result result = messageProcessor.getResult(message);
cache.put(message, result);
}
message.getReplyChannel().send(cache.get(message));
} catch (OutOfMemoryException e) {
myCache.clear();
runtime.gc();
messages.putBack(message);
}
}
这种解决方案的价值在很大程度上取决于系统设计的其余部分。假设“缓存”具有有限的最大大小,如果程序的另一部分开始占用内存,这可能仍然有用。关键是要确保你的内存释放操作依赖于已经分配的对象,这些对象在尝试释放内存时不会对系统产生更多的内存需求。
答案 3 :(得分:-1)
如果整个应用程序处于不稳定状态,我建议直接退出应用程序以避免更多问题。只需在system.err
之前输出一些内容。
如果只有实例处于不稳定状态,你可以抛出运行时异常,但我认为这是一种危险的方式,因为它们没有义务捕获异常,这可能会导致以后出现一些问题。
我建议简单地重新抛出异常,或者用其他相关信息将其包装在另一个异常中。异常的确切类型将在很大程度上取决于案例(空指针,非法状态,错误等)