Как мне убедиться, что инициализирован только один экземпляр, но из другого класса?

Я недавно прочитал о принципе синглтона, но не совсем понимаю, как я могу инициализировать этот единственный экземпляр класса из другого класса, если конструктором является private. А как мне установить параметры из другого класса, если конструктором должен быть private?

public class Player {

    String name;
    Position p;
    Inventory i;

    private Player(String name, Position p, Inventory i){

    }

    static {
        instance = 
    }

    public static Player getPlayer(){
        return instance;
    }

}

значит, вы неправильно поняли синглтон. В синглтоне нет метода setter. Переменные-члены устанавливаются во время создания экземпляра.

Shubhendu Pramanik 22.05.2018 19:22
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
2
1
628
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Ответ принят как подходящий

Вы должны создать переменную private static Player, а в вашем методе getPlayer() или в статическом блоке создать объект и назначить его указанной выше переменной, если она равна нулю.

public static Player getPlayer(){
    if (player == null){
        player = new Player("name", p, i);
    }
    return player;
}

таким образом вы создаете только один экземпляр.


Простые правила,

  1. Конструктор класса должен быть private.
  2. Сохраните объект в переменной private static.
  3. Создайте получатель для одноэлементного объекта (без сеттеров).
  4. Вы также можете добавить synchronized в геттер, чтобы сделать его потокобезопасным (необязательно).

Этот код не является потокобезопасным. Несколько потоков могут увидеть, что player - это null, и инициализировать разные экземпляры Player. Более того, конструктор по умолчанию не объявлен, вы не можете его использовать

Mạnh Quyết Nguyễn 22.05.2018 19:24

Могу ли я создавать сеттеры для атрибутов объекта или это также противоречит принципу синглтона?

Fabian Zbinden 23.05.2018 18:22

@FabianZbinden Это нормально, если единственным статическим объектом является ваш объект Player. Это означает, что все остальные переменные находятся внутри этого объекта.

Roshana Pitigala 23.05.2018 19:04

В другом классе вы звоните: Player.getPlayer()

Он всегда возвращает единственный статический экземпляр вашего класса. Конструктор является частным, поэтому другой класс не может инициализировать ваш класс через конструктор.

Единственный способ получить ваш экземпляр Player - использовать статический метод Player.getPlayer(), следовательно, он одноэлементный.

public class Player {

    String name;
    Position p;
    Inventory i;


    private static final Player instance = new Player(.....your argument....);

    private Player(String name, Position p, Inventory i){

    } 

    public static Player getPlayer(){
        return instance;
    }

}

и мне понадобится getters для доступа к участникам

Shubhendu Pramanik 22.05.2018 19:24

Просто объявите частное статическое финальное поле INSTANCE как

private static final INSTANCE = new Person(name, p, i);

По сути, при таком подходе вы скрываете конструктор (private) и предоставляет статический метод для получения instance. В методе вы проверяете, есть ли instance, если null, если да, вы инициализируете его с предоставленными аргументами.

Наконец вы возвращаете instance.

Уведомление здесь, если вы вызываете метод getPlayer более одного раза, экземпляр будет создан (и будет таким же при последующих вызовах метода getPlayer) с аргументами, предоставленными при первом вызове статического метода.

public class Player {

    String name;
    Position p;
    Inventory i;

    private static Player instance;

    private Player(String name, Position p, Inventory i){
        // ...
    }

    public static Player getPlayer(String name, Position p, Inventory i){
        if (instance == null) {
            instance = new Player(name, p, i);
        }
        return instance;
    }

}

Кроме того, если вы хотите правильно использовать одноэлементный шаблон, вам не следует устанавливать атрибуты (без методов установки) после создания экземпляра.

Другие вопросы по теме