2017-01-20 2 views
2

Я слежу за этим post, чтобы создать потокобезопасные одноэлементные классы, но в INSTANCE есть ошибка компиляции. Он сказал The blank final field INSTANCE may not have been initialized. Мое требование: я хочу, чтобы 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; 
    } 
} 

Но если я использую код следующим образом, другая ошибка: 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» ... возможно, вам следует бросить «RuntimeException» wrapping 'e'? В любом случае, вы в любом случае будете в таком состоянии ... –

+0

Ошибка «Пустое конечное поле INSTANCE, возможно, не было инициализировано» просто заявляет, что вы не инициализировали поле INSTANCE ... _private static final ServiceSoapBindingStub INSTANCE = null; _ должен избавиться от этого сообщения. Конечно, у Джона есть смысл, вам нужно улучшить свой код всеми средствами. –

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

(. Вы можете поймать исключение для входа, а затем повторно выдать, конечно, - но рассмотреть, будет ли более высокий уровень будет его регистрации в любом случае)

Смежные вопросы