2

I follow this post to create a thread safe singleton classs, but there is an compile error in INSTANCE. It said The blank final field INSTANCE may not have been initialized. My requirement is I want INSTANCE is null and the program log this error and try init this object again. If still fail, the program exit.

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

But If I use the Code as follows, another error: 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;
    }   
} 

But If I use the Code as follows no error pop up.

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

Why this happens?

Community
  • 1
  • 1
shawn
  • 460
  • 3
  • 18
  • 1
    Well yes... you see that TODO? Do it :) What do you *want* to happen if there's an `AxisFault`? Currently you won't have assigned anything to `INSTANCE`... perhaps you should throw a `RuntimeException` wrapping `e`? You're basically hosed at that point anyway... – Jon Skeet Jan 20 '17 at 09:33
  • The error "The blank final field INSTANCE may not have been initialized" simply states that you haven't initialized the field INSTANCE ... _private static final ServiceSoapBindingStub INSTANCE=null;_ should get rid of this message. Of course, Jon has a point, you need to improve your code by all means. – Exception_al Jan 20 '17 at 09:35
  • This removes the error message but not the error. – Jonathan Rosenne Jan 20 '17 at 10:53
  • @JonSkeet I want `INSTANCE` is null and the program log this error and try init this object again. If still fail, the program exit. `RuntimeException` is OK. But `RuntimeException` is unchecked exception, I want use checked exception. Any advise? – shawn Feb 01 '17 at 09:16

1 Answers1

2

Given what you've said, you shouldn't be using class initialization for this. In particular:

  • You want to try multiple times
  • You want to use a checked exception

Both of those are feasible, but you'll need to move the initialization into the getInstance method:

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

(You can catch the exception to log it and then rethrow, of course - but consider whether a higher level would be logging it anyway.)

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194