Как я могу получить доступ к переменным экземпляра окружающего класса из анонимного класса?

Как получить доступ к instance variables из метода анонимного класса?

class Tester extends JFrame {

   private JButton button;
   private JLabel label;
   //..some more

   public Tester() {
        function(); // CALL FUNCTION
   }

   public void function() {
      Runnable r = new Runnable() {
         @Override
         public void run() {
            // How do I access button and label from here ?
         }
      };
      new Thread(r).start();
   }
}

person saplingPro    schedule 05.04.2013    source источник
comment
Вы просто получаете к ним доступ, и на самом деле с этим не должно возникнуть никаких проблем. Что именно не работает?   -  person Hovercraft Full Of Eels    schedule 05.04.2013
comment
@HovercraftFullOfEels Как вы думаете, как это сработает? this.Foo ищет объект superclass, который не является Tester, а безымянным классом, который мы называем анонимным внутренним классом.   -  person saplingPro    schedule 05.04.2013
comment
@saplingPro: ваш комментарий не имеет смысла. Что такое this.Foo?   -  person Hovercraft Full Of Eels    schedule 05.04.2013


Ответы (3)


Как получить доступ к instance variables из метода анонимного класса?

Вы просто получаете к ним доступ, если это необходимо:

class Tester extends JFrame {

   private JButton button;
   private JLabel label;
   //..some more

   public Tester() {
        function(); // CALL FUNCTION
   }

   public void function() {
      Runnable r = new Runnable() {
         @Override
         public void run() {
            System.out.println("Button's text is: " + button.getText());
         }
      };
      new Thread(r).start();
   }
}

Более важно: почему это не работает для вас?

person Hovercraft Full Of Eels    schedule 05.04.2013
comment
Я делал this.label. Причина! - person saplingPro; 05.04.2013
comment
@saplingPro: в этой ситуации нет необходимости квалифицировать вашу переменную с помощью this, если только не возникает конфликт имен - две переменные с одинаковыми именами, одна во внутреннем и одна во внешнем классе. В этом случае ответ Джаррода будет правильным. Но ваш вопрос никогда не говорил нам, что вы использовали this для начала, сделав его очень запутанным и неполным вопросом. - person Hovercraft Full Of Eels; 05.04.2013

То, что вы ищете, является полным адресом, так как они не помечены final

final Runnable r = new Runnable() {
public void run() {
    Tester.this.button // access what you need
    Tester.this.label  // access what you need
}};

Вы используете тот же шаблон доступа для Anonymous Inner Classes при создании ActionListeners и других вещей.

Это объясняется в спецификациях как 15.8. 4 Уточнил это, то, что проголосовавший против, по-видимому, не читал. И код для понимания тоже не читал.

person Community    schedule 05.04.2013

следующий код может объяснить вам формат IncloseingClassName.this.VariableName;

class Tester extends JFrame {
int abc=44;//class variable with collision in name
int xyz=4 ;//class variable without collision in name
public Tester() {
function(); // CALL FUNCTION  
}
public void function() {
Runnable r = new Runnable() {
int abc=55;//anonymous class variable
     @Override
     public void run() {
      System.out.println(this.abc);  //output is 55        
      System.out.println(abc);//output is 55 
      System.out.println(Tester.this.abc);//output is 44 
      //System.out.println(this.xyz);//this will give error
      System.out.println(Tester.this.xyz);//output is 4 
      System.out.println(xyz);//output is 4 
            //output is 4 if variable is declared in only enclosing method 
            //then there is no need of Tester.this.abcd ie you can directly 
            //use the variable name if there is no duplication 
            //ie two variables with same name hope you understood :)

     }
  };
  new Thread(r).start();
   }  }
person Swap    schedule 30.06.2014