Java Can';无法定义私有静态final变量,因为它会引发异常

Java Can';无法定义私有静态final变量,因为它会引发异常,java,exception,initialization,Java,Exception,Initialization,我有一门课,像: public class SomeClassImpl implements SomeClass { private static final SomeLib someLib = new SomeLib(); } 我不能这样做,因为SomeLib抛出了一个未知的后异常 我知道我可以将实例化移到构造函数中,但是有没有一种方法可以让我按照上面的方式来实现呢?这样我就可以将var标记为final 我试图寻找如何在类级别抛出异常,但找不到任何异常。您可以使用静态初始值设定项: p

我有一门课,像:

public class SomeClassImpl implements SomeClass {
   private static final SomeLib someLib = new SomeLib();
}
我不能这样做,因为SomeLib抛出了一个未知的后异常

我知道我可以将实例化移到构造函数中,但是有没有一种方法可以让我按照上面的方式来实现呢?这样我就可以将var标记为final


我试图寻找如何在类级别抛出异常,但找不到任何异常。

您可以使用静态初始值设定项:

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;
   }
}
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);
    }
}
请注意,我们需要使用一个临时变量来避免“变量someLib可能尚未初始化”错误,并处理这样一个事实,即由于它是
final
,我们只能分配
someLib
一次


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

您可以使用静态初始值设定项:

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;
   }
}
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(我不记得是哪一个)

如果初始化变量很可能失败,那么静态变量很可能不太可能


静力学有利于[有效]不可变的,(小心)不可变的缓存和其他一些功能。

甚至比以下解决方案稍微优雅一点:


此示例代码将向您介绍如何使用静态方法初始化多个Varibale,而不使用out:

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

我的答案准确无误,但你的答案带有代码,并且比我的答案早几秒发布。1+up-vote。但是这个库实际上是一个数据库的连接池,我厌倦了创建一个临时变量,以防它创建这个池的两个实例?顺便问一下,我如何在创建这个SomeClassImpl类时强制调用方捕获异常?我不知道如何在类级别抛出。在Java中,所有非原语变量都是引用,因此这里只有一个SomeLib实例,其中tmp和SomeLib都引用了该实例。您所说的“创建类”是什么意思?安装还是装载?至于实例化,您可以通过声明构造函数抛出已检查的异常来强制客户机处理异常。至于加载:如果你不能在静态初始值设定项中处理你的异常,你可能不应该通过不使字段为静态来抛出它。这也会导致应用程序崩溃!是的,我更喜欢让它立即崩溃,而不是等待NullPointerException发生。如果应用程序不能崩溃,最好是像我在回答中写的那样懒洋洋地初始化字段。别误会,我同意你的看法,但这正是他不想要的。。。如果你问我使用这样一个最终的静态字段,它在构造函数中抛出一个异常,这是一个糟糕的体系结构,它不应该以这种方式实现,除了非常罕见的原因…那么你建议我怎么做?这是一个mongodb类(Mongo),它是数据库的连接池。