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

我有一个类:

public class SomeClassImpl implements SomeClass { private static final SomeLib someLib = new SomeLib(); } 

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

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

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

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

 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; } } 

请注意,我们需要使用临时变量来避免“变量some​​Lib可能尚未初始化”错误,并且应对这样一个事实,即由于它是final ,我们只能分配someLib一次。

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

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

 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); } } 

请注意,如果您这样做,您的课程将无法初始化。 也许你应该在需要时尝试懒惰地初始化lib。 这样的类初始化exception很难诊断,因为它们被转换为ClassNotFoundException或NoClassDefFoundError(我不记得哪一个)

甚至比Adam Zalcman的解决方案更优雅一点:

 public class SomeClassImpl implements SomeClass { private static final SomeLib someLib = initSomeLib(); private static SomeLib initSomeLib() { SomeLib someLib = null; try { someLib = new SomeLib(); } catch (UnknownHostException uhe) { // Handle exception. } return someLib; } } 

如果初始化变量可能会失败,那么它可能是一个不稳定的候选者。

静态有利于[有效]不可变,(小心)不可变的缓存和其他很少。

此示例代码将为您提供有关使用静态方法初始化多个varibales的想法:

 public class SomeClass implements SomeOtherClass{ private String string1= getValues("/var/log/log1.txt"); private String component = getValues("/var/log/log2.txt"); private String getValues(String file) { try { return new Scanner(new File(file)).next(); }catch(FileNotFoundException ioe){ System.out.println("File not found :: " +ioe); } return null; }