Предотвращение вызова частного конструктора из класса в Java - PullRequest
9 голосов
/ 23 мая 2010

Мы можем ограничить создание объекта класса, сделав его конструктор закрытым. Но этот конструктор все еще можно вызывать из класса. Есть ли способ предотвратить это в Java?

Спасибо.

Ответы [ 5 ]

14 голосов
/ 23 мая 2010

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

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

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

9 голосов
/ 23 мая 2010

Если это личное и вы не хотите, чтобы оно вызывалось в своем собственном классе, есть простой способ предотвратить такую ​​вещь: не пишите код, который вызывает его более одного раза.Вы автор класса.Зачем вам писать код, чтобы вы сами не могли делать то, что находится под вашим контролем?

Его нельзя вызывать вне класса, не прибегая к размышлению.Если вы не хотите, чтобы он вызывался более одного раза в классе, просто не делайте этого.Зачем писать код для предотвращения действия, которое вы можете не выполнять?

Давайте рассмотрим:

Мы можем ограничить создание объекта класса, сделав его конструктор закрытым.

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

Но этот конструктор все еще можно вызыватьот в пределах класса.Есть ли способ предотвратить это в Java?

ОП просит запретить вызов ограниченного конструктора внутри класса.

Если эти два оператора верныПожалуйста, объясните, почему должна быть логика, предотвращающая вызовы конструктора.

Вот типичное использование частного конструктора:

public class Singleton
{
    private static final Singleton instance = new Singleton();

    public static void main(String[] args)
    {
        Singleton singleton = Singleton.getInstance();

        System.out.println(singleton);
    }

    private Singleton() {};

    public static Singleton getInstance() { return Singleton.instance; }

    public String toString() { return Singleton.class.getName(); }
}

Я не вижу смысла запрещать вызовчастному конструктору.

6 голосов
/ 23 мая 2010

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

Однако вы можете сделать это:

private static int count = 0;

private MyClass(){
    if(++count>1)throw new IllegalStateException(); //allow exactly one instantiation
}
3 голосов
/ 23 мая 2010

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

2 голосов
/ 24 мая 2010

Если вы делаете синглтон, лучше всего использовать перечисления:

public enum MySingleton {
    INSTANCE;
    // add methods & stuff here
}

// Usage:
MySingleton.INSTANCE.doSomething();

"Singletonicity" гарантируется JVM - будет только один экземпляр.

...