Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

this keyword in java

Tags:

java

this

keyword

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.

like image 891
user3391344 Avatar asked Mar 07 '14 06:03

user3391344


4 Answers

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

like image 105
sanbhat Avatar answered Sep 23 '22 01:09

sanbhat


"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 !

like image 34
M2hp Avatar answered Sep 23 '22 01:09

M2hp


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:

  1. 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.

  2. 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.

like image 45
Nishant Avatar answered Sep 23 '22 01:09

Nishant


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.

like image 40
Dawood ibn Kareem Avatar answered Sep 23 '22 01:09

Dawood ibn Kareem