I am current reading a java tutorial from Oracle in the inner class section.
Please refer to this link
There is some code that I do not understand in the tutorial.
Can somebody please explain to me how this code below in the DataStructure
class works?
DataStructureIterator iterator = this.new EvenIterator();
Should the outer class not be before DataStructureIterator iterator
and this.new EvenIterator()
like below:
DataStructure.DataStructureIterator iterator = DataStructure.this.new EvenIterator();
I have searched around for a while but I have not found any answer.
The declaration DataStructure.DataStructureIterator iterator = DataStructure.this.new EvenIterator();
is valid, but redundant in that method's context.
Consider this scenario, where there are conflicting inner classes
public void printEven() {
Thread t = new Thread(new Runnable() {
@Override
public void run() {
//Makes EvenIterator point to DataStructure's implementation
DataStructureIterator itr = DataStructure.this.new EvenIterator();
}
class EvenIterator implements DataStructureIterator {
@Override
public boolean hasNext() {
return false;
}
@Override
public Integer next() {
return null;
}
@Override
public void remove() {
}
}
});
}
As you can see the anonymous class Runnable
has inner class named EvenIterator
(which has same name as Outer class's inner class). So writing just
DataStructureIterator itr = this.new EvenIterator(); //OR DataStructureIterator itr = new EvenIterator();
will refer to Runnable
's EvenIterator
. To point to DataStructure
's EvenIterator
, you might want to write
DataStructureIterator itr = DataStructure.this.new EvenIterator();
Which says, I want EvenIterator
to be created on current instance of DataStructure
, not current instance of Runnable
"this keyword" refer to the scope of an object class so :
public class Test {
public void method1(){
this. //this in here refer to "Test" class
}
public class InnerTest {
public void method2(){
this. //this in here refer to "InnerTest" class
}
}
}
now take a look at "this keyword" in this example :
public class Test {
public void method1(){
InnerTest innerTest = this.new InnerTest(); //within the scope of Test class, there's a inner class call InnerTest. create an instance of it !
//OR
TestInterface innerTest2 = this.new InnerTest(); //within the scope of Test class, there's a inner class call InnerTest. create an instance of it !
}
public class InnerTest implements TestInterface{
public void method2(){
Test.this.method1(); //within the scope of "Test" class call the method method1
}
}
}
take note that you can use this keyword to chain the constructor of a class as well. take a look at this example:
public class Test {
public Test() {
this(0);
}
public Test(int r) {
// Do Something Here
}
}
Conclusion:
"this" keyword acts like a pointer to the scope of a class and using "this" you can point to a specific class and do whatever you want.
You can also use "this" keyword to chain class constructors as well !
public class DataStructure {
/** omitted */
public void printEven() {
//#1
DataStructureIterator iterator = this.new EvenIterator();
/** Omitted */
}
//#2
private class EvenIterator implements DataStructureIterator {
/** Omitted */
}
}
So this is the bare-bone problem.
Lets see what we have:
A class DataStructure
that has a non-static method printEven
. the this
keyword in this class will always represent the current instance/object of this class: DataStructure
.
An inner class, that is private. This means this class is not visible outside. It is not static that means you need an instance of outer-class to be able to instanciate this class-member (aka inner class).
So, we want to create an instance of EvenIterator
, we will need a. an instance of outer class, b. call a constructor of inner class.
DataStructureIterator iterator = this.new EvenIterator();
| `---- Call to constructor
`-------------- instance of outer class
Doing DataStructure.this
in DataStructure
is redundant. Because we know that we are in the scope of DataStructure
so just this
will do. However, if you are in inner class EvenIterator
, and you want to explicitely access outer class's instance you will have to to do DataStructure.this
, because in inner class this
will mean the instance of EvenIterator
.
The keyword this
is actually written in the outer class, not the inner class, in your specific example. Therefore, it's not ambiguous in any way - it can only refer to the DataStructure
instance. It's therefore unnecessary (but legal) to qualify it as DataStructure.this
in this case. If you used this
within the inner class, and you intended it to refer to the DataStructure
instance, you would have to write DataStructure.this
.
According to the Java Language Specification 15.8.3 -
The type of this is the class C within which the keyword this occurs.
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