2016-04-05 2 views
0

У меня есть вопрос для лучшего понимания синглтонного шаблона в Java. В частности, меня интересует приватная статическая переменная, которая является экземпляром класса, статическая переменная которого она есть. Моя проблема заключается в том, чтобы понять, что происходит, когда вы создаете статическую переменную с помощью частного конструктора. Этот объект является экземпляром класса, чей экземпляр переменной есть, но это означает, что внутри этого объекта является другой экземпляр этого класса, внутри которого находится другой, и т.д. Для того, чтобы проверить, что я написал следующий код:Очертание Singleton

public class SingletonTest { 
private static SingletonTest s=new SingletonTest(); 
int x=0; 

private SingletonTest(){} 


public static void increase(int y){ 
    s.x=s.x+y; 
} 


public static void main(String [] args){ 

    SingletonTest.increase(5); 
    System.out.println(SingletonTest.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s.x); 

} 
} 

Отпечатано 5. Что означает объект внутри объекта внутри объекта и т. Д., Потому что есть значение переменной SingletonTest.ssssssssssssssssssx с его значением. Любое разъяснение, что на самом деле происходит, когда линия

private static SingletonTest s=new SingletonTest(); 

выполнено? Сколько объектов внутри объектов создано? Это должно быть бесконечно, но это невозможно. Так как верхний код работал, должно быть много. Синглтон должен создавать только один объект, но это не так, потому что внутри каждого экземпляра есть другое. И почему этот код выдал результат 5, когда только s.x увеличен, а не s.s.s .... s.x? Каждый объект внутри объекта должен иметь свой собственный x. Спасибо за любые разъяснения по этому вопросу.

+0

Это один объект, и он является общедоступным. – marcellorvalle

+0

«Что означает объект внутри объекта внутри объекта» Нет, вы просто получаете доступ к статической переменной через экземпляр, который допускается, но подвержен ошибкам. –

+0

Обратите внимание, что если вы хотите реализовать настоящий синглтон, вам нужно сделать окончательную вашу переменную s, чтобы предотвратить дальнейшую модификацию, другими словами, она должна быть частной статической окончательной SingletonTest s = new SingletonTest(); –

ответ

0

можно определить следующим образом:

private static SingletonTest s=new SingletonTest(); 

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

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

+0

Но внутри этого статического объекта (поскольку он сделан в проекте SingletonTest) должна быть одна переменная экземпляра x и другая переменная экземпляра s, которая снова является объектом, а внутри этого объекта должен быть другой x и другой объект s ... Если нет, если есть только один объект класса в виде переменной экземпляра, что внутри этого объекта вместо переменных экземпляра x и s, особенно s? – Seba

+0

@Seba - только что изменил мой ответ. Взглянуть. – marcellorvalle

+0

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

0

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

class Recursive { 
    public Recursive me; 
    private String message = "sayHello"; 

    public Recursive() { 
     me = this; 
    } 

    public void sayHello() { 
     System.out.println(message); 
    } 

} 

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

Recursive rec = new Recursive(); 
rec.me.me.me.me.me.sayHello(); 
0

Спасибо за ответ, но ваш ответ на самом деле не охватывает то, что я пытался спросить ... В моих строках, конструктор называется в той же строке, где определена переменная экземпляра ... Ваш код избежать этого ... код:

public class RekurzivTester { 
public RekurzivTester r=new RekurzivTester(); 
private RekurzivTester(){} 
    public static void main(String[] args) { 
     RekurzivTester rek=new RekurzivTester(); 
} 
} 

производит ошибку переполнения стека. Мое объяснение состоит в том, что потому, что когда был создан новый объект в main(), была запущена бесконечная цепочка объекта-внутри-объекта, но если вы добавите статическую во вторую строку, больше нет ошибки переполнения стека. Объяснение состоит в том, что существует только один объект для каждого класса, к которому обращаются с rek.r, rek.rr и т. Д., Но все же, поскольку выражение rek.rrrrrr ... имеет смысл, это означает, что внутри r еще есть r из которых другая и т. д. (до бесконечности), но все они имеют доступ к тому же объекту, который является классом. Я прав?