【发布时间】:2010-02-26 06:47:37
【问题描述】:
根据我对Java语言的理解,静态变量可以在static initialization block初始化。
但是,当我尝试在实践中实现这一点时(static 变量也是 final),我收到下面屏幕截图中显示的错误:
【问题讨论】:
根据我对Java语言的理解,静态变量可以在static initialization block初始化。
但是,当我尝试在实践中实现这一点时(static 变量也是 final),我收到下面屏幕截图中显示的错误:
【问题讨论】:
当然是的:static final 变量可以在静态块中初始化但是....在那个例子中你有隐式 GOTO(try/catch 本质上是一个 'GOTO catch如果发生了不好的事情')。
如果抛出异常,您的 final 变量将不会被初始化。
请注意,使用静态结构违背了面向对象的教条。它可能会使您的测试复杂化并使调试更加困难。
【讨论】:
static initialization block 抛出异常吗?当static initialization block 中的代码抛出一些我不想处理的异常时,我该怎么办。
e.printStackTrace() 本身在一个 catch 块中让我哭了。
您可以这样做,但您需要通过抛出异常来退出静态块 - 您可以重新抛出已捕获的异常或新异常。通常,此异常必须是RuntimeException。您真的不应该捕获通用的 Exception 而是可能从您的 try 块中抛出的更具体的异常。最后,如果静态初始化程序抛出异常,那么它将在特定运行期间使类不可用,因为 JVM 只会尝试初始化您的类一次。后续尝试使用该类将导致另一个异常,例如NoClassDefFoundError。
所以,为了工作,你的初始化程序应该是这样的:
static {
try {
...
} catch (Exception e) {
e.PrintStackTrace();
throw new InitializationFailedException("Could not init class.", e);
}
}
假设InitializationFailedException 是自定义RuntimeException,但您可以使用现有的。
【讨论】:
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 或一般 Exception,则程序不应尝试使用 myVar。但是,如果这些被捕获并且程序没有结束,那么您需要编写代码来观察和处理 myVar 是否为空(或者对 NullPointerExceptions 的出现感到满意)。
我不确定有什么好的方法来处理这个问题。
【讨论】:
你能把声明放在 finally 块中吗?
try {
//load file
} catch(IOException e) {
// horay
} finally {
HOST=config.get......
}
【讨论】: