Java: когда эта переменная инициализируется?

public class MainMDI extends javax.swing.JFrame {

   private static MainMDI thiz; 

      public MainMDI() {
        initComponents();
        thiz = this;
      }
}  

Я создаю приложение MDI в разгаре. Класс MainMDI является основным классом приложения, поэтому основной метод находится в этом классе. Приведенный выше код создает статическую переменную с именем thiz, которая указывает на экземпляр класса MainMDI при запуске приложения.

Я планирую использовать переменную thiz для доступа к нестатическим (экземплярным) членам класса MainMDI из основного метода (я не могу получить доступ к нестатическим членам из основного метода, поскольку основной метод является статическим членом в классе MainMDI в моем приложении).

public class MainMDI extends javax.swing.JFrame {

   private static MainMDI thiz = this; 

      public MainMDI() {
        initComponents();
      }
}  

Но когда я пытаюсь инициализировать переменную thiz, как в приведенном выше коде, компилятор говорит, что это нестатическая переменная, на которую нельзя ссылаться из статического контекста. Но я не имею в виду это в статическом контексте, не так ли? Это потому, что переменная this, будучи нестатической, еще не инициализирована, когда инициализируется статическая переменная this?

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


person PrashanD    schedule 12.03.2013    source источник
comment
Похоже, вам нужен синглтон. Гугл для этого   -  person Bohemian♦    schedule 12.03.2013
comment
Нет, мне не нужно делать синглтон класса MainMDI. Я просто хочу иметь основной метод внутри класса MainMDI, и я хочу, чтобы основной метод имел доступ к членам экземпляра класса MainMDI.   -  person PrashanD    schedule 12.03.2013
comment
@Prashan Предоставляя статическую переменную (также известную как один), которая ссылается на экземпляр (известный как один) вашего класса, вы эффективно ограничиваете количество доступных экземпляров вашего класса до < i>one (по крайней мере, в контексте, в котором вы думаете, что вам нужно получить доступ через статический метод). Иметь несколько экземпляров и сделать доступным только последний через статический thiz — это то, что можно было бы решить по-разному, поэтому все неявно исключают этот вариант. Следовательно, мы все думаем, что вам действительно нужен одноэлементный подход. Если вы продолжаете настаивать на ответе нет!, вам придется описать свой сценарий.   -  person class stacker    schedule 12.03.2013
comment
@ClassStacker Спасибо за комментарий. Вот сценарий: Обратите внимание, что класс MainMDI расширяет JFrame. В основном методе он создается как новый MainMDI().setVisible(true);. Этот JFrame после создания экземпляра действует как родитель нескольких JInternalFrames в моем приложении. Я считаю, что это воплощение произойдет только один раз. Основной метод будет выполняться только один раз сверху вниз. Будет создан только один экземпляр класса MainMDI. У меня не будет нескольких экземпляров, а только последний будет доступен через thiz. У меня будет только один экземпляр, и он будет доступен (для основного статического метода) через thiz.   -  person PrashanD    schedule 12.03.2013
comment
@Prashan Почему бы тебе просто не оставить ссылку на объект? У меня пока нет четкого представления об архитектуре вашего программного обеспечения, но я полагаю, что это не единственная ссылка, которая вам понадобится в вашем приложении. В таких случаях я бы зарегистрировал объект в объекте среды, который доступен везде, где мне это нужно. Он может быть даже статическим, потому что в моем приложении наверняка будет только одна среда. Тем не менее, если я обнаружу, что мне нужно больше ссылок на объекты MainMDI, изменения кода будут ограничены классом среды и несколькими местами, где мне нужен MainMDI.   -  person class stacker    schedule 12.03.2013
comment
Ну, новый MainMDI().setVisible(true); оператор находится внутри анонимного внутреннего класса new Runnable(){}. Поэтому я выбрал эту альтернативу созданию и сохранению ссылки на экземпляр класса MainMDI внутри внутреннего класса Runnable с последующим доступом к нему.   -  person PrashanD    schedule 12.03.2013
comment
@Prashan И JInternalFrame.getParent() не избавляет вас от необходимости хранить ссылку на родителя JFrame отдельно?   -  person class stacker    schedule 12.03.2013
comment
Ссылочная переменная JInternalFrame не является статической, а код ее объявления генерируется и блокируется для редактирования средой IDE Netbeans. Невозможно использовать его внутри статического метода main. Я мог бы получить к нему доступ через переменную this. thiz.jInternalFrame1.getParent();   -  person PrashanD    schedule 12.03.2013
comment
@Prashan На самом деле я имел в виду не main, а места в коде, когда вам нужен доступ к вашему объекту MainMDI. Должна быть причина, почему вы хотите получить к нему доступ, чтобы иметь доступ к контексту, не так ли? Я думал, что контекст может быть объектом JInternalFrame. -- В любом случае, решение за вами, мы все указали вам на некоторые способы сделать это так, как это должно быть сделано, так что наслаждайтесь, и я надеюсь, что у вас все получится.   -  person class stacker    schedule 12.03.2013
comment
Спасибо. Я надеюсь на это тоже. Многое зависит от этого.   -  person PrashanD    schedule 12.03.2013
comment
@Prashan Так ты обещал сделать что-то, чего не можешь? Хотите узнать мою почасовую ставку? ;)   -  person class stacker    schedule 12.03.2013
comment
@ClassStacker Если я сделаю это сам, моя почасовая ставка увеличится. Но все равно скажи.   -  person PrashanD    schedule 12.03.2013


Ответы (2)


Но когда я пытаюсь инициализировать переменную thiz, как в приведенном выше коде, компилятор говорит, что это нестатическая переменная, на которую нельзя ссылаться из статического контекста. Но я не имею в виду это в статическом контексте, не так ли?

Да Вы. Статические переменные класса инициализируются при загрузке класса (а не при создании экземпляра объекта). В этом контексте нет this. Код:

private static javax.swing.JFrame thiz = this; 

Просто не будет работать. Несмотря на ваши утверждения об обратном, вам действительно нужен синглтон. В противном случае, учитывая N возможных экземпляров объекта MainMDI, к какому из них вы ожидаете получить доступ из статического контекста? Вы должны подумать о рефакторинге своего кода, а не пытаться навязать семантику языка Java.

person Perception    schedule 12.03.2013
comment
Все еще нет. Мне не нужен одноэлементный класс, потому что нет опасности многократного создания экземпляра класса MainMDI в моем приложении. Замечание принято по поводу рефакторинга кода, но я не могу удержаться от сильного оружия. Таким образом, я натыкаюсь на подобные проблемы и чему-то учусь. - person PrashanD; 12.03.2013
comment
Я думаю, вам нужен синглтон Прашан. Не для предотвращения нескольких экземпляров вашего объекта, а для поддержки инициализации поля из статического контекста, как вы пытаетесь сделать. Но в любом случае, если объект создается только один раз, зачем вам thiz? - person vikingsteve; 12.03.2013
comment
@vikingsteve Спасибо за комментарий. Как именно singleton может поддерживать инициализацию поля из статического контекста? Я хотел бы знать больше. И чтобы ответить на ваш вопрос, если вы правильно прочитаете вопрос, вы поймете, почему. МНЕ НУЖНА переменная this для доступа и только для доступа к членам экземпляра класса MainMDI из основного метода. (Основной метод является статическим, и его внутренний класс MainMDI. Это эффективно делает все члены экземпляра класса MainMDI недоступными для основного метода напрямую ИЛИ через переменную this. Поэтому я использую это для доступа к ним) - person PrashanD; 12.03.2013
comment
Ну, я думаю, вы можете либо создать экземпляр MainMDI в своем основном методе (избегая необходимости полного доступа к членам из статического контекста, если можете), либо попробовать Одиночка с инициализацией Eager следующим образом: private static final javax.swing.JFrame INSTANCE = new MainMDI(); - person vikingsteve; 12.03.2013

this означает "экземпляр объекта, с которым в данный момент работают", это имеет смысл только внутри нестатической функции-члена. В общем случае this неявно передается каждой нестатической функции-члену при вызове этой функции-члена, поэтому было бы справедливо сказать, что она инициализируется прямо перед вызовом нестатической функции-члена.

Является ли хорошей идеей выделение класса с «основным» методом, будет сильно зависеть от фактических деталей реализации.

person sharptooth    schedule 12.03.2013