1

这是我的 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 作为参数传递?

如果可能的话,请用简单的语言解释一下!

4

3 回答 3

1

BookReader中,final变量this$0将保存对BookReader的包含Book实例的引用。这是final因为它是由每个BookReader实例的创建时间、创建方式确定的,并且此后不能更改。

在类Book中,静态方法access$000是一种有利于类的合成访问器方法Book.BookReader。作为 的内部类Book,每个BookReader都可以访问其包含实例的成员变量,但 Java 运行时实际上并不知道这一点,并且类文件格式对其没有特殊表示。

因此,BookReader为了能够访问privatemember Book.pageNumber,编译器为此在 class 中生成一个合成的默认访问方法Book,并BookReader根据该方法写入对外部类变量的访问。

于 2015-03-17T13:48:26.633 回答
0

非静态内部类具有对其父实例的引用。那就是

final Book this$0;

对父 Book 实例的引用不能在运行时更改,这就是它是 final 的原因。也就是说,您的 BookReader 具有对 Book 的引用,该引用是在构造时分配的,以后无法更改。

该行:

static int access$000(Book);

是包级别的静态访问器方法。它用于允许内部类访问外部的私有成员。

于 2015-03-17T13:40:13.257 回答
0

您通过以下方式定义BookReader

class Book {
    private class BookReader {  }
}

此类依赖于Book正在创建的实例,因此编译器创建引用并使其成为最终的(这是每个Book实例都可以创建的优化BookReader

如果您定义BookReader为:

class Book {
    private static class BookReader {  }
}

然后引用将不存在,因为可以在没有 Book 实例的情况下创建 Book reader。

这里

于 2015-03-17T13:41:18.600 回答