The commonly used syntax:

public class Foo
{
    private int x;

    public Foo(int x)
    {
        this.x=x;
    }
}

Is actually "flawed." If you have an anonymous inner class inside the Foo constructor (i.e. if this were a GUI code and you were adding an ActionListener) then the private variable x of the Foo class cannot actually be accessed, because it is being overshadowed by the local variable x. And since anonymous inner classes can't access local variables, it will report an error. So you might be inclined to solve this the same way you referenced the field variable the first time with "this.x" However, that doesn't work in this case either, because the object "this" now refers to is the anonymous inner class contained in the constructor that has no private variable x. In other words, from that inner class there is no way to access the instance variable x, because the local variable x overshadows it. The only way I can think of to get around this is to use different names for the local and instance variables so no shadowing is going on. Just an insight I had that I thought I'd share ;)

Btw, if someone does find a way to access the instance variable x under these conditions, please let me know =)

Well Sorry to burst the bubble here, But there is a well known work around for the problem you mentioned. If you need to access the Class member in your inner class in the above situation use the following syntax:-

<Outer_Class_Name>.this.<Member_Name>

The following example should drive the point home:-
(Note have used a Method Local Inner Class instead of an anonymous inner class just to simplify the example)

public class OuterClassDemo {
  // The displayText variable of the OuterClass
  private String displayText="OuterDisplay";

  public OuterClassDemo() {
    // Here we are declaring the local displayText variable,
    // it has been declared as "final" as I want to access it
    // inside the inner class methods
    final String displayText="LocalDisplay";
    class InnerClass {
      public void show() {
        System.out.println("OuterDisplay : " + OuterClassDemo.this.displayText);
        System.out.println("Local DisplayText : " + displayText);
      }
    };

    // Instantiate the inner class and invoke the show() method.
    InnerClass ic = new InnerClass();
    ic.show();
  }

  public static void main(String[] args) {
    new OuterClassDemo();
  }
}

The output the above program would give is:-

stephen@home:~$ java OuterClassDemo
OuterDisplay : OuterDisplay
Local DisplayText : LocalDisplay

So as you see there is no problem in accessing the "displayText" variable of the outer class, even though the method/constructor in which the class is declared has a local variable with the same name.

Edited 6 Years Ago by stephen84s: n/a

Comments
Solid, insightful post. Good catch :)

Oh right, because the way encapsulation works that variable can be accessed by the inner class without a getter or setter, so calling OuterClassName.[direct variable reference] would have no issue. Good point ^^

You can also write your own eg. ActionListener that takes in the parent in its constructor so it can access local variables in its 'parent' .. ie. construct your own implementation of an actionlistener that takes in some interface in its constructor (that the parent implements) and work away

You can also write your own eg. ActionListener that takes in the parent in its constructor so it can access local variables in its 'parent' .. ie. construct your own implementation of an actionlistener that takes in some interface in its constructor (that the parent implements) and work away

Now would you please clarify how does that even connect with the topic under discussion ????
In the first post it is clear the O.P. wanted to just discuss how the local variable in the method was hiding the outer class variable in the inner class.

Edited 6 Years Ago by stephen84s: n/a

Comments
erasing balmark's negative rep.
arrogant fucker

Now would you please clarify how does that even connect with the topic under discussion ????
In the first post it is clear the O.P. wanted to just discuss how the local variable in the method was hiding the outer class variable in the inner class.

Let me dumb it down for you.

class MyActionListener implements ActionListener{
	int x = 0;
	DumbedDownforstephen84s dope = null;
	
	public MyActionListener(int x){
		this.x = x;
	}
	public MyActionListener(DumbedDownforstephen84s dope){
		this.dope = dope;
	}
	public void actionPerformed(ActionEvent ae){
		System.out.println(x);
		// or if you want to keep taking from the dopes X while processing, use the exposed method getX
		System.out.println(dope.getX());
	}
}

public class DumbedDownforstephen84s extends JButton{
	int x=0;
	public DumbedDownforstephen84s(int x){
		MyActionListener myInnerclass = new MyActionListener(this);
	or
		MyActionListener myInnerclass = new MyActionListener(x);
		addActionListener(myInnerclass);
	}

	public int getX(){
		return x;
	}
	public void setX(int x){
		this.x = x;
	}

If you want to screw about with crap like 'OuterClassDemo.this.displayText' I'm glad you don't work for me, I assume your code is unreadable you arrogant little fish.

If you want to screw about with crap like 'OuterClassDemo.this.displayText' I'm glad you don't work for me, I assume your code is unreadable you arrogant little fish.

The Java tutorials make extensive use of anonymous inner classes and there are numerous articles online explaining their advantages. I assume the reason you don't use them is because you don't understand the syntax, but that doesn't mean that someone who does use them has "unreadable" code - quite the opposite actually.

I agree with BJSJC here... your approach looks interesting and advanced balmark, but at the same time it seems like a circuitous route to achieve a simple objective, which stephen's code seems to do. Both approaches seem valid, but unless I were using the MyActionListener class for purposes other than the one previously stated it seems like a far longer approach. Not to mention that if your only objective is to access the instance variable of the outer class, I find the stephen's shorter code far more readable. However, I would definitely consider balmark's approach in the event that I needed the MyActionListener class for other purposes as well. But in the initial posing of the question I was just using ActionListener as an example of a time I would use an anonymous inner class -- I wasn't dealing with all the capabilities of the interface.

I just read balmark's code because all those comments got me curious.
What the buck was that???
I mean seriously can this code be characterized simple or efficient or any useful at all. Why would anyone do this?
I see two classes, one extends JButton and the other implements ActionListener. And the way one is instantiated using the others reference is, I don't know.

I mean no one does this anymore?

public class Frame extends JFrame implements ActionListener {
   JButton butt = new JButton("aaaa");

   ....
   butt.addActionListener(this);

   ....
   
   public void actionPerformed(ActionEvent ae) {
      ....
   }
}

Why extend JButton if the only thing you will do is pass an ActionListener as a parameter, when you can "add" it directly to the JButton itself. And why implement ActionListener as a seperate class, since it is an interface and a class can implement as many interfaces as you want? Or you can have an inner class implement ActionListener.

Now if you say that I am out of topic because the issue here was inner classes, then so is the code posted by balmark, which like I said, I can't seem to understand its usefulness.

Edited 6 Years Ago by javaAddict: n/a

Actually I don't do

public class Frame extends JFrame implements ActionListener

but not for the reasons posted by you. ;-)

I try not to extend the Swing classes, at all unless I specifically need to alter their behaviour, which I almost never do. I prefer composition to extension in Swing (and many other areas). I also do not have the "component" class implement the listeners as I feel this (and the previous point) is a single class doing too many things, and as being responsible for too much. It is also (in both points) very bad in terms of MVC separation, as it will probably being doing at least a bit of all of it.

For some simple one-off "small" application, say a MineSweeper or something, go ahead and have at it, otherwise ....

Actually I don't do

public class Frame extends JFrame implements ActionListener

but not for the reasons posted by you. ;-)

I try not to extend the Swing classes, at all unless I specifically need to alter their behaviour, which I almost never do. I prefer composition to extension in Swing (and many other areas). I also do not have the "component" class implement the listeners as I feel this (and the previous point) is a single class doing too many things, and as being responsible for too much. It is also (in both points) very bad in terms of MVC separation, as it will probably being doing at least a bit of all of it.

For some simple one-off "small" application, say a MineSweeper or something, go ahead and have at it, otherwise ....

Ok.

I have to explain why I extended it in an example?

Ok ..

I did it because the topic was about adding inner classes within a constructor, I figured it'd be easier to understand using methods and classes people know also so I could expose the variable X without using outer.inner.var .. which in my opinion is VERY much more readable.. those who haven't had to read through others code I'm sure will disagree with me though, but hey, I just have real world experience with this. JButton has 'addActionListener' which everyone knows, so I used it instead of making up my own which would only confuse the matter further for some.

Who cares what I extended, it was to add an inner class that can read local variables.

BTW, that was not meant to be knock on you, or anything, so I hope you didn't take it that way. ;-)

Don't worry. I am always interested in learning new different ways to do things.

This article has been dead for over six months. Start a new discussion instead.