I couldn't understand the behavior of the below code.
My expectation was that it should print 100 in both println()
methods. Why the result is different?
If I uncomment getX()
method in inner class, then the output of println(
) methods are the same which is 100.
I couldn't figure out the reasoning of different behavior. Please help me to understand.
public class Foo {
public static void main(String[] args) {
MyOuter outerObj = new MyOuter();
MyOuter.MyInner innerObj = outerObj.new MyInner();
innerObj.setX();
System.out.println("x: " + innerObj.getX()); //x: 3
System.out.println("x: " + outerObj.getX()); //x: 100
}
}
class MyOuter {
private int x = 3;
public int getX() { return x; }
class MyInner extends MyOuter {
public void setX(){ x = 100; }
// public int getX() { return x; }
}
}
In the case of normal or regular inner classes, without an outer class object existing, there cannot be an inner class object. i.e., an object of the inner class is always strongly associated with an outer class object.
An inner class in Java is defined as a class that is declared inside another class. Inner classes are often used to create helper classes, such as views or adapters that are used by the outer class. Inner classes can also be used to create nested data structures, such as a linked list.
To instantiate an inner class, you must first instantiate the outer class. Then, create the inner object within the outer object with this syntax: OuterClass outerObject = new OuterClass(); OuterClass. InnerClass innerObject = outerObject.
In Java, just like methods, variables of a class too can have another class as its member. Writing a class within another is allowed in Java. The class written within is called the nested class, and the class that holds the inner class is called the outer class.
From MyInner
's perspective, there are two private int x
fields in play here:
super.x
that is inherited from MyOuter
, but inaccessible because it is declared as private
, and MyInner
as an inheriting object cannot access this field.MyOuter.this.x
from the sorrounding MyOuter
-instance (since MyInner
is a (non-static) inner class, it is always bound to an instance of the surrounding MyOuter
), that is accessible.The method setX()
in MyInner
cannot access the inherited field super.x
, thus it accesses the field MyOuter.this.x
and sets its values to 100
. A consecutive call on the surrounding MyOuter
's getX()
will return 100
.
The call innerObj.getX()
(which is inherited from MyOuter
and can access super.x
) returns the value of the inherited field super.x
(still having its initial value of 3
).
If we remove the extends MyOuter
from and include the getX()
-method in MyInner
, the code behaves as expected.
The fact that MyInner
cannot access the inherited field private x
is confusing at first, but the behaviour is actually in line with the behaviour of the keyword protected
in the context of static mehthods in inheriting classes as discussed in this post by Hariharan
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With