这是我的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已作为参数传递到此处?
请尽可能简单地解释一下!
答案 0 :(得分:1)
在BookReader
中,final
变量this$0
将包含对包含BookReader
个实例的Book
的引用。这是final
,因为在创建该实例时,通过其创建方式确定每个BookReader
实例,并且此后不能更改。
在类Book
中,静态方法access$000
是一种合成访问器方法,有利于类Book.BookReader
。作为Book
的内部类,每个BookReader
都可以访问其包含实例的成员变量,但Java运行时实际上并不知道这一点,并且类文件格式没有特殊的表示形式。
因此,BookReader
能够访问 private
成员Book.pageNumber
,编译器会在课堂上为此目的生成合成的默认访问方法Book
,并在BookReader
中根据该方法写入对外类变量的访问。
答案 1 :(得分:0)
非静态内部类具有对其父实例的引用。
final Book this$0;
无法在运行时更改对父Book实例的引用,这就是最终的原因。也就是说,您的BookReader完全引用了在构造时分配的Book,并且以后无法更改。
该行:
static int access$000(Book);
是包级静态访问器方法。它用于允许内部类访问外部的私有成员。
答案 2 :(得分:0)
您可以通过以下方式定义BookReader
class Book {
private class BookReader { }
}
此类依赖于正在创建的Book
实例,因此编译器会创建引用并使其成为最终(这是一个优化,因为每个Book
实例都可以创建BookReader
)
如果您通过以下方式定义BookReader
:
class Book {
private static class BookReader { }
}
然后引用将不存在,因为可以在没有Book实例的情况下创建Book阅读器。
请参阅here。