Wednesday, June 25, 2008

Java Inner Class Expert

Puzzle 1
Given the following code:

1. class MyOuter {
2. private int x = 7;
3. class MyInner {
4. public void seeOuter() {
5. System.out.println("Outer x is " + x);
6. }
7. }
8. }


What is happening when we try compile the code?
If you think, the output is Compilation fails then you're wrong. Line 5 looks interesting, because a private member is accessed from an inner class.

Is it possible?
Yes, it is. Remember, inner classes can access the outer class members.
So the right answer is: the code compiles without error.

Puzzle 2
Given the following code:

01. class MyOuter {
02. private int x = 7;
03. public void makeInner() {
04. MyInner in = new MyInner();
05. in.seeOuter();
06. }
07. class MyInner {
08. public void seeOuter() {
09. System.out.println("Outer x is " + x);
10. System.out.println("Inner class ref is " + this);
11. System.out.println("Outer class ref is " + MyOuter.this);
12. }
13. }
14. public static void main (String[] args) {
15. MyOuter.MyInner inner = new MyOuter().new MyInner();
16. inner.seeOuter();
17. }
18. }

What is happening when we try compile the code?
Line 11 and line 15 can be strange, but both are absolutely correct.
See the line 11 first:
11. System.out.println("Outer class ref is " + MyOuter.this);

To reference the “outer this” (the outer class instance) from within the inner
class code, we can use .this.

Line 15:
15. MyOuter.MyInner inner = new MyOuter().new MyInner();


To access the inner class, we must have an outer class instance. If we have one then the <OuterClassInstance>. new <InnerClassConstructorglt; create a new inner class instance.
So the right answer is: the code compiles without error.

Puzzle 3
Given the following code:

01. class MyOuter {
02. private String x = "Outer";
03. void doStuff() {
04. String z = "local variable";
05. class MyInner {
06. public void seeOuter() {
07. System.out.println("Outer x is " + x);
08. System.out.println("Local variable z is " + z);
09. }
10. }
11. }
12. }

What is happening when we try compile the code?

The result is Compilation fails. The problem is with the line 8:
MyInner is a Method-Local Inner class and the Method-Local Inner classes can not access the local variables.

Of course, there is an exception:
If the local variable is marked as final then it can be accessed from a Method-Local Inner class.

2 comments:

Yom said...

Purely theoritical, but any answer welcome

Given

Class ContansMethodWithInner{
void methodWithInner(){
final int x = 0;
Class InnerInMethod{
int x = 1;
void seeX(){
System.out.println(x);
}
}
}
}

A call to seeX() will print the inner class variable with value 1.
What is the syntax to print the method local final variable WITH SAME NAME x value 0 ?

Thnaks for your answer

Peter Szilagyi said...

The variable x in the inner class hides the method x variable. It isn't possible to access the outer x after declaring the inner through this name. Java cannot do this.

The most simply way is renaming the x field in the inner class.
Other way is creating a new reference to the outer x before it's hided. Value of x is copied to variable outX and can be accessed.


Thanks for your question.

...Peter