Ankur Anand
Ankur Anand

Reputation: 3904

Relationship between Inner and Outer Class in Java?

This is my Book.java code

public class Book {
    private int pageNumber;

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

When I complied it and used javap I got following things for the two classes

For Book$BookReader.class

This is the output code

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

My question is why final is added while making any reference here and why this reference was made? What is its use in innerclass?

For Book.class

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

Why static is added for variable and why Book has been passed as parameter here?

Please explain it in simple terms if possible!

Upvotes: 1

Views: 536

Answers (3)

bhspencer
bhspencer

Reputation: 13560

A non static inner class has a reference to its parent instance. That is the

final Book this$0;

The reference to the parent Book instance cannot be changed at run time, which is why it is final. Which is to say your BookReader has a reference to exactly on Book that is assigned on construction and cannot be changed later.

The line:

static int access$000(Book);

Is a package-level static accessor method. It is used to allow the inner class access the private members of the outer.

Upvotes: 0

John Bollinger
John Bollinger

Reputation: 180276

In BookReader, the final variable this$0 will hold a reference to the BookReader's containing Book instance. This is final because it is determined for each BookReader instance when that instance is created, by the manner of its creation, and cannot thereafter change.

In class Book, the static method access$000 is a synthetic accessor method for the benefit of class Book.BookReader. As an inner class of Book, each BookReader has access to the member variables of its containing instance, but the Java runtime does not actually know this, and the class file format has no special representation for it.

For BookReader to be able to access private member Book.pageNumber, therefore, the compiler generates a synthetic, default-access method for that purpose in class Book, and in BookReader writes accesses to the outer class's variable in terms of that method.

Upvotes: 1

Neilos
Neilos

Reputation: 2746

You define BookReader by:

class Book {
    private class BookReader {  }
}

This class relies on an instance of Book being created therefore the compiler creates the reference and makes it final (this is an optimisation as each Book instance can create BookReader)

If you defined BookReader by:

class Book {
    private static class BookReader {  }
}

Then the reference would not exist as a Book reader can be created without an instance of Book.

See here.

Upvotes: 0

Related Questions