Это ключевое слово в java

В настоящее время я читаю учебник по Java из Oracle во внутреннем разделе класса.

Обратитесь к эта ссылка

В учебнике есть код, который я не понимаю.

Может кто-нибудь, пожалуйста, объясните мне, как работает этот код ниже в классе DataStructure?

DataStructureIterator iterator = this.new EvenIterator();

Если внешний класс не должен быть до DataStructureIterator iterator и this.new EvenIterator(), как показано ниже:

DataStructure.DataStructureIterator iterator = DataStructure.this.new EvenIterator();

Я искал вокруг какое-то время, но я не нашел ответа.

Ответ 1

Объявление DataStructure.DataStructureIterator iterator = DataStructure.this.new EvenIterator(); является допустимым, но избыточным в этом контексте метода.

Рассмотрим этот сценарий, где существуют конфликтующие внутренние классы

public void printEven() {
    Thread t = new Thread(new Runnable() {

        @Override
        public void run() {
            //Makes EvenIterator point to DataStructure 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() {
            }

        }
    });
}

Как вы видите, анонимный класс Runnable имеет внутренний класс с именем EvenIterator (который имеет то же имя, что и внутренний класс Outer class). Так что писать просто

DataStructureIterator itr = this.new EvenIterator(); //OR DataStructureIterator itr = new EvenIterator();

будет ссылаться на Runnable EvenIterator. Чтобы указать на DataStructure EvenIterator, вы можете написать

DataStructureIterator itr = DataStructure.this.new EvenIterator();

Что говорит, я хочу, чтобы EvenIterator был создан в текущем экземпляре DataStructure, а не в текущем экземпляре Runnable

Ответ 2

"это ключевое слово" ссылается на область действия класса объекта:

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
        }
     }
}

теперь взгляните на "это ключевое слово" в этом примере:

public class Test {
     public void method1(){

         InnerTest innerTest = this.new InnerTest(); //within the scope of Test class, there a inner class call InnerTest. create an instance of it !
         //OR
         TestInterface innerTest2 = this.new InnerTest(); //within the scope of Test class, there 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
        }
     }
}

обратите внимание, что вы можете использовать это ключевое слово, чтобы связать конструктор класса. посмотрите на этот пример:

public class Test {

    public Test() {
        this(0);
    }

    public Test(int r) {
        // Do Something Here
    }
}

Вывод:

"this" ключевое слово действует как указатель в области класса и с помощью "this" вы можете указать на определенный класс и делать все, что хотите.

Вы также можете использовать ключевое слово "this" для конструкторов классов цепей!

Ответ 3

public class DataStructure {
    /** omitted */

    public void printEven() {
       //#1
       DataStructureIterator iterator = this.new EvenIterator();
       /** Omitted */
    }

    //#2
    private class EvenIterator implements DataStructureIterator {
      /** Omitted */
    }
}

Итак, это проблема с голой костью.

Давайте посмотрим, что у нас есть:

  • Класс DataStructure, который имеет нестатический метод printEven. ключевое слово this в этом классе будет всегда представлять текущий экземпляр/объект этого класса: DataStructure.

  • Внутренний класс, частный. Это означает, что этот класс не виден снаружи. Это не является статичным, что означает, что вам нужен экземпляр внешнего класса, чтобы иметь возможность инициировать этот член класса (он же внутренний класс).

Итак, мы хотим создать экземпляр EvenIterator, нам понадобится a. экземпляр внешнего класса, b. вызовите конструктор внутреннего класса.

  DataStructureIterator iterator = this.new EvenIterator();
                                     |        `---- Call to constructor
                                     `-------------- instance of outer class 

Выполнение DataStructure.this в DataStructure избыточно. Потому что мы знаем, что мы находимся в области DataStructure, поэтому просто this будет делать. Однако, если вы находитесь во внутреннем классе EvenIterator и хотите явно получить доступ к экземпляру внешнего класса, вам нужно будет сделать DataStructure.this, потому что во внутреннем классе this будет отображаться экземпляр EvenIterator.

Ответ 4

Ключевое слово this фактически написано во внешнем классе, а не в внутреннем классе, в вашем конкретном примере. Поэтому он не является двусмысленным - он может ссылаться только на экземпляр DataStructure. Поэтому нет необходимости (но юридически) квалифицировать его как DataStructure.this в этом случае. Если вы использовали this внутри внутреннего класса и предположили, что он ссылается на экземпляр DataStructure, вам нужно написать DataStructure.this.

В соответствии с Спецификация языка Java 15.8.3 -

Тип этого класса C, в котором это ключевое слово встречается.