这是我的书.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 在这里作为参数传递?
如果可能的话,请用简单的术语解释一下!
在BookReader
中,final
变量this$0
将包含Book
实例的BookReader
的引用。 这是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 { }
}
那么引用将不存在,因为如果没有 Book 实例,可以创建 Book 阅读器。
看这里。
非静态内部类具有对其父实例的引用。那就是
final Book this$0;
对父 Book 实例的引用无法在运行时更改,这就是它是 final的原因。也就是说,您的 BookReader 有一个对 Book 的引用,该引用是在构造时分配的,以后无法更改。
该行:
static int access$000(Book);
是包级静态访问器方法。它用于允许内部类访问外部类的私有成员。