根据我对Java语言的理解,可以在static initialization block
中初始化静态变量。
但是,当我尝试在实践中实现这一点时(static
变量final
也是如此),我会得到以下屏幕截图中显示的错误:
答案 0 :(得分:35)
是的当然可以:static final
变量可以在静态块中初始化,但是 ....在该示例中你有隐式GOTO(try/catch
本质上是'GOTO捕获,如果发生了不好的事情')。
如果抛出异常,您的final
变量将不会被初始化。
请注意,静态构造的使用违背了面向对象的教条。它可能会使您的测试复杂化并使调试变得更加困难。
答案 1 :(得分:18)
您可以执行此操作,但需要通过抛出异常来退出静态块 - 您可以重新抛出已捕获的异常或新异常。通常,此例外必须是RuntimeException
。你真的不应该抓住一个通用的Exception
,但可能会从try
块中抛出更具体的异常。最后,如果静态初始化程序抛出异常,那么它将在该特定运行期间使该类不可用,因为JVM将仅尝试初始化您的类一次。后续尝试使用此类将导致另一个异常,例如NoClassDefFoundError
。
所以,要工作,你的初始化程序应该是这样的:
static {
try {
...
} catch (Exception e) {
e.PrintStackTrace();
throw new InitializationFailedException("Could not init class.", e);
}
}
假设InitializationFailedException
是自定义RuntimeException
,但您可以使用现有的。{/ p>
答案 2 :(得分:9)
public class MyClass
{
private static final SomeClass myVar;
static
{
Object obj = null; // You could use SomeClass, but I like Object so you can reuse it
try
{
obj = new SomeClass(...);
}
catch(WhateverException err)
{
// Possibly nested try-catches here if the first exception is recoverable...
// Print an error, log the error, do something with the error
throw new ExceptionInInitializerError(err);
}
finally
{
myVar = (SomeClass) obj;
}
}
}
假设没有上游位置可以捕获 ExceptionInInitializationError 或一般异常,那么程序不应该尝试使用 myVar 。然而,如果这些被抓住并且程序没有结束,那么你需要编码来监视并处理 myVar 为空(或者对NullPointerExceptions
全部出来感到满意)。< / p>
我不确定有什么好方法可以解决这个问题。
答案 3 :(得分:0)
你能把声明放在finally块吗?
try {
//load file
} catch(IOException e) {
// horay
} finally {
HOST=config.get......
}