1. Inner classes

You recently learned that there are static variables and static methods. It turns out that there are also static classes. But we'll approach this topic from a distance.

In Java, you are entirely allowed to declare classes within classes. And even classes within classes that are within classes within classes. It all looks very simple:

class OuterClass
{
   variables of the class
   methods of the class

   class NestedClass
   {
      variables of the class
      methods of the class
   }
}

We just declare one class inside another. As simple as that.

Example:

public class Solution
{
   static ArrayList<Point> points = new ArrayList<Point>();

   public static void main(String[] args)
   {
      Point point = new Point();
      point.x = 100;
      point.y = 200;
      points.add(point);
   }

   static class Point
   {
      int x;
      int y;
   }
}

Nested classes can be static or non-static. Static nested classes are simply called static nested classes. Non-static nested classes are called inner classes (inner classes).



2. Static classes

Static nested classes can be used outside of their outer class. If such a class has the public access modifier, then it can be used anywhere in the program. Such classes are almost indistinguishable from any ordinary class. But there are a couple of differences.

Class name

If you want to refer to a static nested class from somewhere other than its outer class, you need to specify the class name, which consists of the name of the outer class and the name of the nested class. Here's the general appearance of this name:

OuterClass.InnerClass

Examples:

Outer class Nested class Full name of the nested class
com.codegym.Solution
Point
com.codegym.Solution.Point
java.util.Map
Entry
java.util.Map.Entry
java.util.Files
DirectoryStream
java.util.Files.DirectoryStream
java.nio.WindowsPath
Closeable
java.nio.WindowsPath.Closeable

If a nested class has its own nested class, their names are simply joined using a dot.

A typical example of a nested class in the JDK is the Entry class inside of Map class. If you want to get the set of key-value pairs stored in a HashMap object, then use the entrySet() method, which returns a Set<Map.Entry>.

Note that Map.Entry is an example of an outer class and a nested class.

Creating an object

It's very easy to create an object of a static nested class. This is how it looks:

OuterClass.NestedClass name = new OuterClass.NestedClass();

It's all the same as with ordinary classes, but the name consists of two parts.

Calling static methods

If a static class has static methods, you can access them in the same way as the static methods of ordinary classes (but the class name will consist of two parts).

OuterClass.NestedClass.staticMethod();

Accessing static variables

Accessing the public static variables of a nested class is easy too:

OuterParent.NestedClass.nameOfStaticVariable


3. Features of static classes

Static nested classes have the least reason to be called static. They behave just like regular classes. There are no restrictions on accessing them from non-static methods.

If you're working with a static nested class inside its outer class, you won't notice any difference from the most ordinary (not nested and not static) class.

Example:

Static nested Point class Ordinary Point class.
public class Solution
{
   static ArrayList<Point> points;

   public static void main(String[] args)
   {
      Point point = new Point();
      point.x = 100;
      point.y = 200;
      points = new ArrayList<Point>();
      points.add(point);
   }

   static class Point
   {
      int x;
      int y;
   }
}
public class Solution
{
   static ArrayList<Point> points;

   public static void main(String[] args)
   {
      Point point = new Point();
      point.x = 100;
      point.y = 200;
      points = new ArrayList<Point>();
      points.add(point);
   }
}

class Point
{
   int x;
   int y;
}

If you take some static nested class and move it out of its outer class, the only thing that will change is that the new class will no longer be able to access the private static variables and methods of its former outer class.

Example:

Static nested Point class Ordinary Point class.
public class Solution
{
   private static ArrayList<Point> points;

   static class Point
   {
      int x;
      int y;

      public static void main(String[] args)
      {
         Point point = new Point();
         point.x = 100;
         point.y = 200;

         // This will work
         points = new ArrayList<Point>();
         points.add(point);
      }
   }
}
public class Solution
{
   private static ArrayList<Point> points;
}

class Point
{
   int x;
   int y;

   public static void main(String[] args)
   {
      Point point = new Point();
      point.x = 100;
      point.y = 200;

      // This will generate an error
      points = new ArrayList<Point>();
      points.add(point);
   }
}

The main method in the ordinary Point class cannot access the private static points variable of the Solution class!

This is the main difference between a static nested class and an ordinary class. Methods of a static nested class can access all the static variables and methods of their outer class, even if they are declared private.

And if you think about it, why should that be surprising? The private modifier explicitly says that the variables and methods marked by this modifier can only be accessed from within their class. Is a static nested class inside its outer class? Yes, so no problem! Access them as much as you want.