java - 空白的最终字段 INSTANCE 可能尚未初始化

标签 java design-patterns singleton

我关注这个post创建线程安全的单例类,但 INSTANCE 中存在编译错误。它说空白的最终字段实例可能尚未初始化。我的要求是我希望 INSTANCE 为空并且程序记录此错误并再次尝试初始化此对象。如果仍然失败,则程序退出。

public  class ServiceConnection {
    private static class SingletonObjectFactoryHolder{
      private static final ServiceSoapBindingStub  INSTANCE;
      static
         {
            try {
                INSTANCE = new ServiceSoapBindingStub();

            } catch (AxisFault e) {
               // TODO Auto-generated catch block
               e.printStackTrace();             
            }
         }  
    }

    public static ServiceSoapBindingStub getInstance() {
        return SingletonObjectFactoryHolder.INSTANCE;
    }   
} 

但是如果我按如下方式使用代码,则会出现另一个错误:最终字段 INSTANCE 可能已被分配

public  class ServiceConnection {
    private static class SingletonObjectFactoryHolder{
      private static final ServiceSoapBindingStub  INSTANCE;
      static
         {
            try {
                INSTANCE = new ServiceSoapBindingStub();

            } catch (AxisFault e) {
               INSTANCE = null;
               e.printStackTrace();             
            }
         }  
    }

    public static ServiceSoapBindingStub getInstance() {
        return SingletonObjectFactoryHolder.INSTANCE;
    }   
} 

但是如果我使用如下代码,则不会弹出错误。

public  class ServiceConnection {
    private static class SingletonObjectFactoryHolder{
      private static final ServiceSoapBindingStub  INSTANCE;
      static
         {
            try {
                INSTANCE = new ServiceSoapBindingStub();

            } catch (AxisFault e) {
               e.printStackTrace();
               throw new RuntimeException();                    
            }
         }  
    }

    public static ServiceSoapBindingStub getInstance() {
        return SingletonObjectFactoryHolder.INSTANCE;
    }   
}

为什么会发生这种情况?

最佳答案

鉴于您所说的,您不应该为此使用类初始化。特别是:

  • 您想多次尝试
  • 您想要使用受检查的异常

这两种方法都是可行的,但您需要将初始化移至 getInstance 方法中:

public  class ServiceConnection {
    private static final Object lock = new Object();
    private static ServiceSoapBindingStub instance;

    public static ServiceSoapBindingStub getInstance() throws AxisFault {
        // Note: you could use double-checked locking here if you really
        // wanted.
        synchronized (lock) {
            if (instance == null) {
                instance = new ServiceSoapBindingStub();
            }
            return instance;
        }
    }   
}

(当然,您可以捕获异常以记录它,然后重新抛出 - 但请考虑更高级别是否会记录它。)

关于java - 空白的最终字段 INSTANCE 可能尚未初始化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41760197/

相关文章:

java - 更改和发送全局所需的数据

java - 如何在 JavaFX 中异步执行需要一些 GUI 操作的较长运行任务?

java - 使用 AsyncTask 进行网页抓取

design-patterns - 外观和适配器模式有什么区别?

c# - 'TryParse' 或 'TryGetValue' 的示例实现

java - 在不使用单例的情况下将类限制为一个实例?

java - 二进制转十六进制无预定义方法(JAVA)

java - 如何使用where条件获取Sqlite中的列总和?

java - 合并使用不同对象的重复代码

c# - .Net 应用程序范围的变量