Introduction to nested classes in Java
Tags: java, tutorial, architecture
Published: 2019-10-31 06:17:28

---
title: Introduction to nested classes in Java
published: true
description: 
tags: java, tutorial, architecture
cover_image: https://images.pexels.com/photos/2663853/pexels-photo-2663853.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=750&w=1260
---

Hi! This post is dedicated to an important concept from Java object oriented programming - nested classes. Speaking simply, nested class is a class, defined inside an another one (outer class). They serve to provide a better level of encapsulation and to organize logically code, that is used in one place only. You also meet nested classes when you work with GUI development (for instance, in Android programming). Finally, if you are serious about passing Oracle exams, you have to master nested classes as tasks with them present on both stages.

In the article we will observe what is a nested class in Java and concrete types of such classes.

## What is a nested class?

From a technical point of view, a nested class is a __class, that is defined inside the another class__. An outer class is also called an _enclosing class_. These classes enable developers to logically group classes that are only used in one place, and therefore this will increase the degree of encapsulation, and will create more readable and maintainable code. Nested classes in Java are divided into two categories: __static__ and __non-static__. First group are also called static nested classes. Non-static nested classes are known as inner classes. Take a look on the graph below, that demonstrates an hierarchy of Java nested classes:

![](https://www.mednikov.net/wp-content/uploads/2019/10/nested-classes-overview.png)

There are several arguments for using nested classes:

1. When a class is useful to only one other class, it is logical to embed it in that class and keep the two together
2. Nesting small classes within top-level classes places the code closer to where it is used
3. An usage of nested classes is strong measure to increase a level of encapsulation

These types of nested classes differ on a basis of scope, accessing of enclosing class members etc. Now, we will investigate each of them more deeper. We will start with static nested classes.

## Static classes

First group to talk is static nested classes group.

### Static nested classes

The static nested class is associated with its enclosing class. It cannot refer directly to instance variables or methods defined in its enclosing class - in other words you have to use an _object reference_. Let have a look on the following example:

```java
class Outer{

	static class Nested{

	}
}

// create nested class instance
Outer.Nested nestedInstance = new Outer.Nested();
```

Note, that in the example code, the static nested class are accessed using the outer class name. The nested class cannot access non-static data members and methods of outer class can access static data members of outer class including those that are declared as _private_. Take a look on the another code snippet:

```java
class Car{

//static members
	static String manufacturer;
	private static String vin;

// instance member
	String model;


	static class Engine{
		System.out.println(manufacturer);
		System.out.println(vin);

	//This will be a compilation error
		System.out.println(model);
	}
}
```

So, what should remember about static nested classes? Following points:

* Static nested classes __can__ access __static members__ of the outer class
* They __can't__ access __instance (non-static) members__ of the outer class __directly__, only using __object reference__ (like __Outer.Nested__)
* Static nested classes are created as __OuterClass.StaticNestedClass nestedObject = new OuterClass.StaticNestedClass();__

Opposite, there are several types of non-static _inner_ classes.

## Non-static classes

Non-static classes are associated with an instance of the enclosing class and have direct access to the enclosing class's methods and fields. Also, because an inner class is associated with an instance of the outer class, it cannot define any static members itself. Let observe types of non-static classes.

### Local inner classes

Local inner classes are classes that are defined in a block, which is a group of zero or more statements between balanced braces. Generally, these classes are defined within a method, however you can define a local class inside any block. Let observe on the code below:

```java
class Outer{

	int value = 10;

	void calculate(){

		class Sum{

			int value;

			Sum(int a, int b){
				this.value = a + b;
			}

			int getValue(){
				return this.value;
			}
		}

		Sum sum = new Sum(20,30);
		System.out.println(sum.getValue());
		System.out.println(value);
	}

	public static void main(String[] args) {
		Outer outer = new Outer();
		outer.calculate();
	}
}
```

So, this example demonstates the concept of _shadowing_: if a declaration of a type (such as a member variable or a parameter name) in a particular scope (such as an inner class or a method definition) has the same name as another declaration in the enclosing scope, then the declaration shadows the declaration of the enclosing scope. In the example we have two __value__ variables and to refer to Sum's member we used __this__ keyword. Declarations of a type (such as a variable) in a local class shadow declarations in the enclosing scope that have the same name.

Talking about local inner class it is also important to talk about accessing _local variables_. Let modify the code above:

```java
void calculate(){

	int y - 10;

	class Multiplicator{

		int x;

		Sum(int x){
			this.value = x * y;
		}

		int getValue(){
			return this.value;
		}
	}

	Multiplicator multiplicator = new Multiplicator(10);
	System.out.println(multiplicator.getValue());
}
```

How can __Multiplicator__ class access a local variable __y__? This is a popular interview question. Local classes can only access local variables that are declared __final__. When a local class accesses a local variable or parameter of the enclosing block, it captures that variable or parameter. But that how it was __before Java 8__. However, in the 8th release was introduced a concept of [effectively final varialbes](https://javarevisited.blogspot.com/2015/03/what-is-effectively-final-variable-of.html): these are variables or parameters whose value is never changed after it is initialized.

While, effectively final variables do not need to have __final__ keyword in front of them, anyway they __can't be changed__ after initialization. Following this principle, this code snipper will not compile:

```java
void calculate(){

	int y - 10;

	class Multiplicator{

		int x;

		Sum(int x){
			this.value = x * y;
		}

		int getValue(){
			return this.value;
		}
	}

	y = 20;

	Multiplicator multiplicator = new Multiplicator(10);
	System.out.println(multiplicator.getValue());
}
```

When we will try to compile it, Java will indicate an error output similar to this one:

![](https://www.mednikov.net/wp-content/uploads/2019/10/nested-classes-effectively-final.png)

Let summarize what we learned so far about local inner classes:

* Local inner class scope is the block where it is defined
* It __can't__ be instantiated from outside the block where it is created
* It _can_ access local variables if they are final (prior to Java 8) or effectively final
* Local inner class has access to the members of its enclosing class

Also, local inner classes can extend an abstract class or can also implement an interface.

### Anonymous classes

Finally let explore anonymous classes. From a technical point of view, they are like local inner classes except that they do not have a name. So we use them only if we require to overload methods of a class or interface, without having to actually extend (implement) it. Let go directly to an example:

```java
void doWork(){
	Runnable runnable = new Runnable() {
		@Override
		public void run() {
			System.out.println("Hello runnable");
		}
	};
	runnable.run();
}
```

We implement a __Runnable__ interface directly inside a method that calls it. This enables to make code more concise. We can to declare and instantiate a class at the same time. You can declare inside an anonymous class fields and extra methods that do not exist inside parent class or interface or even add local classes. However, __you cannot declare constructors in an anonymous class__. 

What is important to remember about anonymous classes:

* They have access to the members of its enclosing class
* Same as local inner classes, they __can't__ access local variables in its enclosing scope that are not declared as final or effectively final.
* Like a nested class, a declaration of a type (such as a variable) in an anonymous class shadows any other declarations in the enclosing scope that have the same name
* An anonymous class can have static members provided that they are constant variables

## Conclusion

In this tutorial we explored different types of nested classes in Java. This topic is very important, so if you are serious about passing Oracle exams, you have to master nested classes as tasks with them present on both stages. We discussed how to use and what are restrictions for each of them. 

## References

* J Steven Perry _Unit 18: Nested classes_ (2016) IBM Developer, [read here](https://developer.ibm.com/tutorials/j-perry-nested-classes/)
* Manoj Debnath _Understanding Java Nested Classes and Java Inner Classes_ (2017) Developer.com, [read here](https://www.developer.com/java/data/understanding-java-nested-classes-and-java-inner-classes.html)