Static and Non-static inner classes in Java

Sarangan Janakan
5 min readJan 9, 2023

--

In Java, non-static inner classes have an implicit reference to the enclosing instance of the outer class. This means that they have access to the instance variables and methods of the outer class, and can be used to create multiple instances of the inner class that are associated with different instances of the outer class.

For example, consider the following code:

class Outer {
private int x;
class Inner {
public void printX() {
System.out.println(x);
}
}
}
Outer outer1 = new Outer();
outer1.x = 5;
Outer.Inner inner1 = outer1.new Inner();
inner1.printX(); // prints 5
Outer outer2 = new Outer();
outer2.x = 10;
Outer.Inner inner2 = outer2.new Inner();
inner2.printX(); // prints 10

Here, the Outer class has an inner class Inner, which has a method printX that prints the value of x from the enclosing Outer instance. The code creates two instances of Outer (outer1 and outer2) and two instances of Inner (inner1 and inner2), each of which is associated with a different instance of Outer. When printX is called on inner1 and inner2, it prints the value of x from the corresponding Outer instance.

Because non-static inner classes have an implicit reference to the enclosing instance, they require additional memory to store this reference. This means that they are slightly less memory-efficient than static inner classes, which don’t have an implicit reference to the enclosing instance and don’t require additional memory for this purpose.

On the other hand, static inner classes can’t access the instance variables or methods of the outer class, so they are more limited in what they can do. They are useful when you want to define a class that is closely related to the outer class and doesn’t need to access its instance variables or methods.

Non-static inner classes (also known as inner classes or inner objects) are useful when you want to define a class that is closely related to another class, and has access to the instance variables and methods of the outer class.

Non- Static inner classes Usages

Here are a few situations where you might want to use a non-static inner class:

  1. When the inner class needs to access instance variables or methods of the outer class that are not static. Because non-static inner classes have an implicit reference to the enclosing instance of the outer class, they can access non-static instance variables and methods directly.
  2. When you want to define multiple instances of the inner class that are associated with different instances of the outer class. For example, you might want to create a non-static inner class Button for a Dialog class, where each Button instance is associated with a different Dialog instance and can access the instance variables and methods of the Dialog instance.

When you want to define a class that is only used within the context of the outer class and is not intended to be used independently. Non-static inner classes can only be accessed from within the outer class, so they are more encapsulated and less prone to being used in unintended ways.

Static inner classes Usages

We can use static inner classes when we don't need to access any instance variables or methods of the outer class, so there is no need for them to have an implicit reference to an enclosing instance of the outer class. This makes them more memory-efficient than non-static inner classes, which do have an implicit reference to the enclosing instance.

Let’s say we need to design graphs and it contains Nodes and edges. The Node and Edge classes are closely related to the Graph class and are only used within the context of a Graph object. Defining them as static inner classes makes it clear that they are part of the Graph class and are not intended to be used independently.

public class Graph {

Map <String, Node> nodeMap;

public Graph () {
nodeMap = new HashMap<>();
}

static class Node {
String name;
List <Edge> edgeList;

public Node(String name) {
this.name = name;
edgeList = new ArrayList();
}
}

static class Edge {
Node source;
Node Destination;
String type;

public Edge(Node source, Node destination, String type) {
this.Destination = destination;
this.source = source;
this.type = type;
}
}

}

Static inner classes cannot access the instance variables or methods

Here is an example that illustrates the fact that static inner classes cannot access the instance variables or methods of the outer class:

class Outer {
private int x;
static class Inner {
public void printX() {
System.out.println(x); // compilation error: cannot access x
}
}
}

In this example, the Outer class has a private instance variable x and a static inner class Inner. The Inner class has a method printX that tries to access the value of x from the enclosing Outer instance. However, this code will not compile, because static inner classes cannot access instance variables or methods of the outer class.

To access the instance variables or methods of the outer class from a static inner class, you can either:

  1. Make the instance variables or methods static as well. This allows the inner class to access them using the outer class name (e.g. Outer.x).
  2. Pass an instance of the outer class to the inner class and store it in a field. The inner class can then access the instance variables or methods of the outer class through this field.

Here is an example that shows how to do this:

class Outer {
private int x;
public void setX(int x) {
this.x = x;
}
static class Inner {
Outer outer;
public Inner(Outer outer) {
this.outer = outer;
}
public void printX() {
System.out.println(outer.x);
}
}
}
Outer outer = new Outer();
outer.setX(5);
Outer.Inner inner = new Outer.Inner(outer);
inner.printX(); // prints 5

In this example, the Outer class has a non-static method setX that sets the value of x, and a static inner class Inner that has a field outer of type Outer. The Inner class has a constructor that takes an Outer instance and stores it in the outer field. The printX method of the Inner class can then access the x field of the outer instance using the outer.x notation.

--

--

Sarangan Janakan
Sarangan Janakan

Responses (1)