【问题标题】:The blank final field INSTANCE may not have been initialized空白的最终字段 INSTANCE 可能尚未初始化
【发布时间】:2017-06-05 05:43:33
【问题描述】:

我按照这个post 创建了一个线程安全的单例类,但是在INSTANCE 中有一个编译错误。它说The blank final field INSTANCE may not have been initialized。我的要求是我希望 INSTANCE 为 null 并且程序记录此错误并再次尝试初始化此对象。如果仍然失败,程序退出。

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

但如果我按如下方式使用代码,则会出现另一个错误:The final field INSTANCE may already have been assigned

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

为什么会这样?

【问题讨论】:

  • 嗯,是的......你看到那个TODO了吗?这样做:) 如果有AxisFault,你想要发生什么?目前你不会给INSTANCE分配任何东西...也许你应该抛出一个RuntimeException包装e?无论如何,你基本上已经被冲洗了......
  • 错误“The blank final field INSTANCE may not have been initialized”只是表明您尚未初始化字段 INSTANCE ... private static final ServiceSoapBindingStub INSTANCE=null; 应该摆脱这个消息。当然,Jon 有一点,你需要通过各种方式改进你的代码。
  • 这会删除错误消息,但不会删除错误。
  • @JonSkeet 我想要INSTANCE 为空,程序记录此错误并再次尝试初始化此对象。如果仍然失败,程序退出。 RuntimeException 没问题。但是RuntimeException 是未经检查的异常,我想使用已检查的异常。有什么建议吗?

标签: java design-patterns singleton


【解决方案1】:

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

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

这两种方法都是可行的,但您需要将初始化移到 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;
        }
    }   
}

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

【讨论】:

    猜你喜欢
    • 2016-04-07
    • 1970-01-01
    • 2017-12-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多