Как я могу реализовать аннотацию @Singleton?

Возможно, повторный вопрос. Но мне нужно реализовать что-то вроде

@Singleton
public class Person {
}

Это обеспечит только один экземпляр объекта Person.

Один из способов - сделать конструктор закрытым. Но это делает аннотацию Singleton излишней.

Я не мог понять, могу ли я действительно ограничить создание объекта единственным объектом, не делая его конструктивным.

Возможно ли это?

Ответ 1

Никакая аннотация не может препятствовать созданию экземпляра класса. Однако, если вы планируете внедрить что-то вроде структуры Injection Dependency или просто простого объекта factory, тогда вы можете использовать отражение, чтобы прочитать аннотацию и предотвратить создание экземпляра более одного раза, но я понимаю, что это не ответ, который вы искали.

На самом деле вы можете подумать о том, чтобы удалить шаблон singleton и перейти к более современному решению, например, к правильной структуре DI, что может дать вам тот же результат - с большей гибкостью.

Ответ 2

public class ASingletonClass
{
    private static ASingletonClass instance = null;
    private ASingletonClass()
    {

    }

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

Это правильный способ реализовать singleton. Аннотации не могут помешать людям вызвать публичный конструктор.

Ответ 3

Пример @Singletone реализация шаблона, потокобезопасная:

        public class SomeDataSource {
            private static volatile SomeDataSource INSTANCE;

            // Prevent direct instantiation.
            private SomeDataSource() {
              // Leave it empty or implement any logic needed
            }

            public static SomeDataSource getInstance() {
                if (INSTANCE == null) {
                    synchronized (SomeDataSource.class) {
                        if (INSTANCE == null) {
                            INSTANCE = new SomeDataSource();
                        }
                    }
                }
                return INSTANCE;
            }

            // Implement some logic
    }

И тогда просто используйте этот код, чтобы получить свой Singletone и быть в безопасности:

SomeDataSource dataSource = SomeDataSource.getInstance();

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

Или вы можете использовать некоторые библиотеки Injection Dependency. Dagger2 например:

@Provides @Singleton static Heater provideHeater() {
  return new ElectricHeater();
}