简体   繁体   English

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

[英]Can't define a private static final variable because it throws an exception

I have a class like: 我有一个类:

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

I can't do this because SomeLib throws a UnknownHostException. 我不能这样做,因为SomeLib会抛出一个UnknownHostException。

I know I could move the instantiation to the constructor, but is there a way for me to do it the way I have it above somehow? 我知道我可以将实例化移动到构造函数中,但是我有办法以某种方式以上面的方式执行它吗? That way I can keep the var marked as final. 这样我就可以将var标记为final。

I tried to look for how to throw exceptions at the class level but can't find anything on it. 我试图寻找如何在类级别抛出异常,但无法在其上找到任何内容。

You can use static initializer: 您可以使用静态初始化程序:

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

Note that we need to use a temporary variable to avoid "variable someLib might not have been initialized" error and to cope with the fact that we can only assign someLib once due to it being final . 请注意,我们需要使用临时变量来避免“变量some​​Lib可能尚未初始化”错误,并且应对这样一个事实,即由于它是final ,我们只能分配someLib一次。

However, the need to add complex initialization logic and exception handling to static initializer is often a sign of a more fundamental design issue. 但是,需要向静态初始化程序添加复杂的初始化逻辑和异常处理通常是更基本的设计问题的标志。 You wrote in the comments section that this is a database connection pool class. 您在评论部分写道,这是一个数据库连接池类。 Instead of using static final consider making it an instance variable. 而不是使用静态最终考虑使其成为实例变量。 You can then do the initialization in a constructor or better yet in a static factory method. 然后,您可以在构造函数中进行初始化,或者更好地在静态工厂方法中进行初始化。

You could use a static initializer: 您可以使用静态初始化程序:

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

Note that your class won't be able to initialize if you do it so. 请注意,如果您这样做,您的课程将无法初始化。 Maybe you should try to initialize the lib lazily, when needed. 也许你应该在需要时尝试懒惰地初始化lib。 Such class initialization exceptions are hard to diagnose, because they're transformed into ClassNotFoundException or NoClassDefFoundError (I don't remember which one) 这样的类初始化异常很难诊断,因为它们被转换为ClassNotFoundException或NoClassDefFoundError(我不记得哪一个)

Even just a little bit more elegant than the solution from Adam Zalcman : 甚至比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;
   }

}

This sample code will gives you an idea on initializing multiple varibales with out using static method: 此示例代码将为您提供有关使用静态方法初始化多个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;
    }

If initialising a variable is likely to fail, then it is likely a poor candidate to be static. 如果初始化变量可能会失败,那么它很可能是一个不稳定的候选者。

Statics are good for [effective] immutables, (with care) caches of immutables and little else. 静态有利于[有效]不可变,(小心)不可变的缓存和其他很少。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM