2012-02-11 3 views
0

Прежде чем задать вопрос, я хотел бы предоставить код для ясности. Ниже приведен мой код для одноэлементного класса.Нужна информация о классе singleton в java

public class CoreData { 

    private boolean VarA; 

    private static CoreData instance = null; 

    protected CoreData() { 
      // Exists only to defeat instantiation. 
    } 

    public static CoreData getInstance() { 
      if(instance == null) { 
      instance = new CoreData(); 
      } 
      return instance; 
    } 

    public boolean getVarA(){ 
     return VarA; 
    } 

    public void setFirstTime(boolean B){ 
     VarA = B; 
    } 
} 

Теперь у меня есть несколько вопросов, чтобы спросить

  1. Что будет разница, если сделать переменную член Vara как статический?
  2. Могу ли я инициализировать переменную-член в методе getInstance()?
  3. Какова наилучшая практика инициализации переменных-членов в классе Singleton?
  4. В чем смысл сделать этот класс окончательным?
  5. В чем смысл создания переменной-члена final.

Я очень новичок в java и OOPS. Я изучаю это сейчас. Буду признателен, если кто-то ответит на мои вопросы, чтобы мои знания были лучше.

+1

Конструктор 'protected' не уничтожает создание (извне),' private' будет делать. –

ответ

0

Какая разница, если сделать переменную-член VarA как static?

Это будет труднее сделать это не позднее одноточечно

Могу ли я инициализировать переменную-член в методе getInstance()?

Да. Почему нет. Но для этого делаются конструкторы.

Какова наилучшая практика инициализации переменных-членов в классе Singleton?

В соответствии с наилучшей практикой вы должны использовать некоторые IoC и не вводить какой-либо код в область видимости вашего логического кода.

В чем смысл создания этого класса как окончательного?

Вы должны использовать private конструктор вместо protected один или сделать его final предотвратить создание нескольких экземпляров за счет расширения. Как new CoreData(){};

В чем смысл создания переменной-члена?

Я считаю, что все переменные должны быть окончательными по умолчанию. Также он может помочь вам с многопоточными проблемами.

+0

Спасибо за ваши ответы. Не могли бы вы немного рассказать, как я могу инициализировать переменные в методе getInstance(). Если я прямо присваиваю значение члену, он говорит мне, что «Невозможно сделать статическую ссылку на нестатическое поле» –

+0

@ Сурья Нараяна Падхи так же, как 'if (instance == null) {instance = new CoreData() ; instance.VarA = false;} ' –

+0

Если все переменные должны быть окончательными по умолчанию, их, вероятно, следует назвать чем-то другим. О, подождите, я знаю ... давайте называть их константами! – Perception

2

Потому что у вас есть только один экземпляр (или так вы думаете - см. Ниже), что делает его статическим не должно иметь никакого значения.

Ваш код не является потокобезопасным! У вас может быть два экземпляра. Причина в том, что после проверки экземпляра null, другой поток также может проверить и найти его null - оба потока будут создавать экземпляры и возвращать их. Можно было бы «убежать».

Традиционный подход «проверил замок», где производится проверка внутри синхронизированный блок, но, как Билл Pugh отметил в своем famous article, что сломанный образец. Java 1.5 ввела ключевое слово volatile, чтобы обойти эту проблему, но это все еще уродливый код.

Современная передовая практика подход к ленивой инициализации экземпляра, чтобы использовать один из этих моделей:

public class CoreData { 

    private static class InstanceHolder { 
     static CoreData INSTANCE = new CoreData(); 
    } 

    public static CoreData getInstance() { 
     return InstanceHolder.INSTANCE; 
    } 
} 

или

public static enum CoreData { 

    INSTANCE; 

    // rest of class 
} 

Оба гарантированы языка для создания одиночек, но версия enum - «железо-плакированная» - возможно, за счет десериализации взлома до влияет состояние экземпляра в шаблоне статического кластера. Помимо этой тонкой уязвимости, оба работают. Я предпочитаю первый вариант в своем коде просто потому, что он избегает раздувания класса.

+0

Спасибо за ваше замечательное предложение сделать его потоковым. Это новая вещь, чтобы учиться на меня. Не могли бы вы немного рассказать, как я могу инициализировать переменные в методе getInstance(). Если я прямо присваиваю значение члену, он говорит мне, что «Невозможно сделать статическую ссылку на нестатическое поле». –

+0

@Bohemian, Спасибо за эту приятную информацию и статью о двойной проверке блокировки. –

+0

Очень хорошо обобщены. +1. – Perception

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