2017-01-20 92 views
2

これは、postに従うと、スレッドセーフなシングルトンクラスを作成しますが、INSTANCEにコンパイルエラーがあります。それはThe blank final field INSTANCE may not have been initializedと言った。私の要件は、INSTANCEがnullで、プログラムがこのエラーを記録し、このオブジェクトを再度初期化しようとしたいということです。それでも失敗すると、プログラムは終了します。空白の最終フィールド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; 
    } 
} 

しかし、次のように、私は、別のエラーコードを使用している場合: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; 
    } 
} 

これはどうしてですか?

+1

まあ...あなたはTODOを見ますか?それを行う:) * AxisFaultがある場合、あなたは何をしたいのですか?現在、 'INSTANCE'には何も割り当てられていません。おそらく' e'をラップする 'RuntimeException'を投げるべきでしょうか?あなたは基本的にその時点でその点にとどまっています... –

+0

"空の最終フィールドINSTANCEが初期化されていない可能性があります"というエラーは、単にINSTANCEフィールドを初期化していないことを示しています... _private static final ServiceSoapBindingStub INSTANCE = null;このメッセージを取り除くべきです。もちろん、Jonにはポイントがあります。コードを是正する必要があります。 –

+0

これにより、エラーメッセージは削除されますが、エラーは削除されません。 –

答えて

2

あなたが言ったことを考えると、このためにクラスの初期化を使用すべきではありません。特に:

  • あなたがチェック例外

それらの両方を使用したい複数回

  • を試してみたいが実現可能であるが、あなたは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; 
         } 
        } 
    } 
    

    (。もちろん、それをログに記録し、その後再スローする例外をキャッチすることができます - しかし、より高いレベルはとにかくそれをログに記録するかどうかを検討)

  • 関連する問題