无法定义私有静态final变量,因为它会抛出异常

Bla*_*man 19 java initialization exception

我有一个类:

public class SomeClassImpl implements SomeClass {
   private static final SomeLib someLib = new SomeLib();
}
Run Code Online (Sandbox Code Playgroud)

我不能这样做,因为SomeLib会抛出一个UnknownHostException.

我知道我可以将实例化移动到构造函数中,但是我有办法以某种方式以上面的方式执行它吗?这样我就可以将var标记为final.

我试图寻找如何在类级别抛出异常,但无法在其上找到任何内容.

Ada*_*man 44

您可以使用静态初始化程序:

public class SomeClassImpl implements SomeClass {
   private static final SomeLib someLib;
   static {
     SomeLib tmp = null;
     try {
       tmp = new SomeLib();
     } catch (UnknownHostException uhe) {
       // Handle exception.
     }
     someLib = tmp;
   }
}
Run Code Online (Sandbox Code Playgroud)

请注意,我们需要使用临时变量来避免"变量some​​Lib可能尚未初始化"错误并且应对我们只能分配someLib一次的事实final.

但是,需要向静态初始化程序添加复杂的初始化逻辑和异常处理通常是更基本的设计问题的标志.您在评论部分写道,这是一个数据库连接池类.而不是使用静态最终考虑使其成为实例变量.然后,您可以在构造函数中进行初始化,或者更好地在静态工厂方法中进行初始化.

  • 在Java中,所有非基本变量都是引用,因此这里只有一个SomeLib实例,而tmp和someLib都引用该单个实例。 (2认同)

JB *_*zet 5

您可以使用静态初始化程序:

private static final SomeLib SOME_LIB; // respect naming conventions

static {
    try {
        SOME_LIB = new SomeLib();
    }
    catch (UnknownHostException e) {
        throw new RuntimeException("Class initialization failed due to UnknownHostException", e);
    }
}
Run Code Online (Sandbox Code Playgroud)

请注意,如果您这样做,您的类将无法初始化。也许您应该在需要时尝试延迟初始化库。此类初始化异常很难诊断,因为它们会转化为 ClassNotFoundException 或 NoClassDefFoundError (我不记得是哪一个)