Отношения между внутренним и внешним классом в Java?

Это мой код Book.java

public class Book {
    private int pageNumber;

    private class BookReader{
        public int getPage(){
            return pageNumber;
        }
    }
}

Когда я выполнил это и использовал javap Я получил следующие вещи для двух классов

За Book$BookReader.class

Это выходной код

Compiled from "Book.jav
class Book$BookReader {
  final Book this$0;
  public int getPage();
}

У меня вопрос, почему final добавляется при упоминании здесь и почему эта ссылка была сделана? Каково его использование во внутреннем классе?

За Book.class

$ javap Book.class
Compiled from "Book.java"
public class Book {
  public Book();
  static int access$000(Book);
}

Почему статические добавлены для переменной и почему Book был передан в качестве параметра здесь?

Пожалуйста, объясните это простыми словами, если это возможно!

3 ответа

Решение

В BookReader, final переменная this$0 будет содержать ссылку на BookReader содержит Book пример. Это final потому что это определяется для каждого BookReader экземпляр, когда этот экземпляр создан, способом его создания, и не может впоследствии измениться.

В классе Book статический метод access$000 это синтетический метод доступа для пользы класса Book.BookReader, Как внутренний класс Book каждый BookReader имеет доступ к переменным-членам содержащего его экземпляра, но среда выполнения Java на самом деле этого не знает, и формат файла класса не имеет для него специального представления.

За BookReader иметь возможность доступа private член Book.pageNumber поэтому компилятор генерирует синтетический метод доступа по умолчанию для этой цели в классе Book, И в BookReader записывает доступ к переменной внешнего класса в терминах этого метода.

Вы определяете BookReader от:

class Book {
    private class BookReader {  }
}

Этот класс опирается на экземпляр Book создается, поэтому компилятор создает ссылку и делает ее окончательной (это оптимизация, поскольку каждый Book экземпляр может создать BookReader)

Если вы определили BookReader от:

class Book {
    private static class BookReader {  }
}

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

Смотрите здесь.

Нестатический внутренний класс имеет ссылку на свой родительский экземпляр. Это

final Book this$0;

Ссылка на родительский экземпляр Book не может быть изменена во время выполнения, поэтому она является окончательной. То есть ваш BookReader имеет ссылку именно на Book, которая назначена на конструкцию и не может быть изменена позже.

Линия:

static int access$000(Book);

Статический метод доступа уровня пакета. Он используется для предоставления внутреннему классу доступа к закрытым членам внешнего.

Другие вопросы по тегам