我有一个类:
public class SomeClassImpl implements SomeClass {
private static final SomeLib someLib = new SomeLib();
}
我不能这样做,因为SomeLib会抛出一个UnknownHostException。
我知道我可以将实例化移动到构造函数中,但有没有办法让我按照上面的方式执行它?这样我就可以将var标记为final。
我试图寻找如何在类级别抛出异常但却找不到任何内容。
答案 0 :(得分: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;
}
}
请注意,我们需要使用临时变量来避免“变量someLib可能尚未初始化”错误,并且应对由于someLib
而我们只能分配final
一次的事实
但是,需要向静态初始化程序添加复杂的初始化逻辑和异常处理通常是更基本的设计问题的标志。您在评论部分写道,这是一个数据库连接池类。而不是使用静态最终考虑使其成为实例变量。然后,您可以在构造函数中进行初始化,或者更好地在静态工厂方法中进行初始化。
答案 1 :(得分:4)
您可以使用静态初始化程序:
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。这样的类初始化异常很难诊断,因为它们被转换为ClassNotFoundException或NoClassDefFoundError(我不记得哪一个)
答案 2 :(得分:2)
甚至比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;
}
}
答案 3 :(得分:0)
如果初始化变量可能会失败,那么它很可能是一个不稳定的候选者。
静态有利于[有效]不可变,(小心)不可变的缓存和其他很少。
答案 4 :(得分:0)
此示例代码将为您提供有关使用静态方法初始化多个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;
}