考虑以下代码:
final MyClass myObject;
try {
myObject = new MyClass(...)
} catch (MyClassException){
// terminate
System.exit(1);
}
myObject.doSomething();
问题是Netbeans编辑器/解析器认为可以在一个单元化对象上调用.doSomething()
,当然情况并非如此。
是否存在规避这种情况的正常/标准模式?我可以调用函数但不愿意这样做。我还不是将整个块都包含在try catch块中,因为没有别的东西会抛出MyClassException
我不是(还有;-))Java语法和模式方面的专家,所以我希望我能错过一些明显的东西。
答案 0 :(得分:5)
您在try
块中初始化对象,这可能会抛出异常,使对象保持未初始化状态。
在你的catch
块中,你停止你的程序,但System.exit(1)
不会停止方法执行,而是terminates currently running JVM - 对于编译器而言,它只是你调用的另一种方法被扔了。
return
实际上会停止执行方法 - 因此不会超出return;
之外的代码。
您可以修改catch
块,如下所示:
catch (MyClassException){
// terminate
System.exit(1);
return;
}
编译器不会抱怨myObject
没有以这种方式初始化。
修改强>
注意:如果你将myObject.doSomething();
放入finally
块编译器会抱怨,因为finally
即使在return
之后也会执行。
finally {
// compiler error
myObject.doSomething();
}
答案 1 :(得分:1)
案例是在try / catch块之外,您尝试在可能未实例化的对象上调用方法。这是因为try / catch块可能会抛出异常,因此不会创建对象,因此在这种情况下,当您尝试在其上调用doSomething()
方法时,您将没有对象。
如果在try / catch块中包含方法调用,它将起作用。
您可以在此处找到相关信息: Java Tutorials: Lesson: Exceptions
答案 2 :(得分:1)
这是我能做的最好的事情:
final MyClass myObject;
{
MyClass local = null;
try {
local = new MyClass(...)
} catch (MyClassException){
// terminate
System.exit(1);
}
myObject = local;
}
myObject.doSomething();
答案 3 :(得分:1)
问题是Netbeans编辑器/解析器认为可以在一个单元化对象上调用.doSomething(),当然情况并非如此。
这种情况:没有什么可以阻止您使用SecurityManager
来禁止System.exit()
退出JVM。在这种情况下,下一个语句可以执行。
从Java语法的角度来看,当您调用myObject
时,编译器需要证明myObject.doSomething();
明确分配了 。
JLS指定可以执行此操作的情况。特别是,可用于确定下一条指令不会被执行的唯一语句是break
,continue
,return
和throw
。因此,不允许编译器认为System.exit(1);
将阻止执行下一个语句。
答案 4 :(得分:0)
Netbeans编辑器/解析器认为.doSomething()可以在一个单元化对象上调用,当然情况并非如此。
你错了。您实际上尝试来初始化变量。编译器在初始化中不“信任”,原因很简单:可以抛出一个异常,你可以抓住但不抛出一个新的{{1}或者制作一个RuntimeException()
。例如:
System.exit(1)
你可以捕获异常,打印堆栈跟踪并继续程序,结果将是try {
myObject = new MyClass(...)
} catch (MyClassException e){
// hey I catch this but do nothing lmao yolo
e.printStackTrace();
}
myObject.doSomething();
。
答案 5 :(得分:0)
始终初始化final
变量和成员的要点。虽然您的代码永远不会调用doSomething
,但它会使最终字段保持未定义状态。如果向try-catch块添加finally
子句,这将成为一个问题 - 当发生异常并且finally
将不可用时,您可以输入myObject
子句,编译器必须避免。一个快速的解决方案是在try块中移动doSomething
调用:
final MyClass myObject;
try {
myObject = new MyClass(...);
myObject.doSomething();
} catch (MyClassException){
// terminate
System.exit(1);
}
只要doSomething
没有抛出MyClassException
,这应该可以正常工作。如果它抛出这样的异常,你可能需要区分它是来自构造函数还是方法(当然这对你的逻辑来说很重要)。