Java中的内外部关系?

时间:2015-03-17 13:35:53

标签: java class javap

这是我的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 个答案:

答案 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