Architecture & DesignUnderstanding Java Nested Classes and Java Inner Classes

Understanding Java Nested Classes and Java Inner Classes

Developer.com content and product recommendations are editorially independent. We may make money when you click on links to our partners. Learn More.

In Java programming, nested and inner classes often go hand in hand. A class that is defined within another class is called a nested class. An inner class, on the other hand, is a non-static type, a particular specimen of a nested class. This article attempts to elaborate on these two ideas of designing classes.

Java Nested Class

A nested class refers to the idea of defining one class inside another class. The scope of the nested class is bounded by the scope of the enclosing classes. That means if Pearl is a class defined within, say, the Oyster class, the object of Pearl cannot exist without the existence of an Oyster object and the class within the class, Pearl, can access all the members of the Oyster class, including private members. But, the external class, such as Oyster, cannot access the members of Pearl class. Here’s an example of the classes’ use:

package ocean;

public class Oyster {

   class Pearl{
      String pearl="member";
      private String privatePearl="private member";
      protected String protectedPearl="protected member";
      public String publicPearl="public member";

      public Pearl() {
         oyster="sdfsds";             // OK!
         privateOyster="sdcdscs";     // OK!
         protectedOyster="svsfdf";    // OK!
         publicOyster="sdfdfsd";      // OK!
      }
   }

   String oyster="member";
   private String privateOyster="private member";
   protected String protectedOyster="protected member";
   public String publicOyster="public member";

   public Oyster(){
      pearl="sddsfsd";                // not OK!
      privatePearl="sdfdfdfs";        // not OK!
      protectedPearl="svsfdf";        // not OK!
      publicPearl="sdfdfsd";          // not OK!
   }
}

A nested class also can be declared locally within a block as well, such as seen in the following example:

package ocean;

public class Oyster {

   public void testfunc(){

      class A{
         private String s="A";
         public String getA(){
            return s;
         }
      }

      {
         class B{
            private String s="B";
            public String getB(){
               return s;
            }
         }

         B b=new B();
         System.out.println(b.getB());
      }

      A a=new A();
      System.out.println(a.getA());
   }
   public static void main(String[] args) {
      Oyster os=new Oyster();
      os.testfunc();
   }
}

Now, the nested class can be of two types, a static nested class and a non-static nested class. A nested class, Pearl, which is declared static with the static modifier, cannot access the members of the enclosing class Oyster directly because the nested class Pearl is now static. As a result, it needs an object of the Oyster class to access the members of its enclosing class. Static nested classes are very rarely used.

package ocean;

public class Oyster {

   static class Pearl{
      String pearl="member";
      private String privatePearl="private member";
      protected String protectedPearl="protected member";
      public String publicPearl="public member";

      public Pearl() {
         oyster="sdfsds";                // Not OK!
         privateOyster="sdcdscs";        // Not OK!
         protectedOyster="svsfdf";       // Not OK!
         publicOyster="sdfdfsd";         // Not OK!

         Oyster os=new Oyster();

         os.oyster="sdfsds";             // OK!
         os.privateOyster="sdcdscs";     // OK!
         os.protectedOyster="svsfdf";    // OK!
         os.publicOyster="sdfdfsd";      // OK!

      }
   }


   String oyster="member";
   private String privateOyster="private member";
   protected String protectedOyster="protected member";
   public String publicOyster="public member";

   // ...

}

Java Inner Class

An inner class is nested but non-static and is the most important of all nested classes. In fact, when we say “nested class,” we most often mean an inner class. It has access to all the members of the outer classes. A class can be nested up to any depth; there is no practical limit, but a class nested deeper that two is almost always unnecessary.

The following example illustrates how to declare inner classes. The program sets up the Book object and then prints the list. The list of Book is encapsulated inside the BookList class, which is maintained as a dynamic list.

An Example Application

package org.mano.example;

public class Book {
   private String title;
   public Book(String title){
      this.title=title;
   }
   public String toString(){
      return title;
   }
}


package org.mano.example;

public class BookList {

   private BookNode list;

   public BookList() {
      list = null;
   }

   public void add(Book book) {
      BookNode node = new BookNode(book);
      BookNode tmpnode;
      if (list == null)
         list = node;
      else {
         tmpnode = list;
      while (tmpnode.next != null)
         tmpnode = tmpnode.next;
         tmpnode.next = node;
      }
   }

   public String toString() {
      String str = "";
      BookNode tmpnode = list;
      while (tmpnode != null) {
         str += tmpnode.book + "n";
         tmpnode = tmpnode.next;
      }
      return str;
   }

   // BookNode is a inner class
   private class BookNode {
      public Book book;
      public BookNode next;

      public BookNode(Book book) {
         this.book = book;
         next = null;
      }
   }
}

package org.mano.example;

public class BookShelf {
   public static void main(String[] args) {

      BookList shelf = new BookList();
      shelf.add(new Book("Harry Potter"));
      shelf.add(new Book("Around the World in 80 Days"));
      shelf.add(new Book("Count of Monte Cristo"));
      shelf.add(new Book("Jataka Tales"));
      shelf.add(new Book("Aesop's Fables"));

      System.out.println(shelf);
   }
}

The important thing to note in the preceding code is that the BookList class uses an inner class, called BookNode, to represent a node in the linked list. Each node contains a reference variable that links to the next node in the list. Because BookNode is an inner class, it is logical to make data values of the class public. This enables that the code in the BookList class to refer to those data values directly.

Conclusion

The idea of nested class gives the flexibility of creating classes almost anywhere it is necessary. Though it is not always required, on occasion it is exactly the inner class that satisfies a need. The idea is illustrated in the previous code. To summarize, a couple of situations where using inner classes seems appropriate are as follows:

  • Inner classes should be created in a situation where there is close relationship between two classes and is not accessed by any other class.
  • Inner classes are very often found in event handling in Java GUI programming. Because of this fact, the relationship between the listener and its GUI component is one of the appropriate situations where inner classes can be used safely.

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Latest Posts

Related Stories