Week 127 — What are nested classes and how do they work?

Question of the Week #127
What are nested classes and how do they work?
6 Replies
daysling
daysling3w ago
Java allows declaring classes within other classes.
public class OuterClass {
// code belonging to OuterClass, e.g. fields, methods and constructors
private String outerClassField = "some non-static field of the outer class";
private static String outerClassStaticField = "some static field of the outer class";

public class NormalNestedClass {
// code belonging to NormalNestedClass, e.g. fields, methods and constructors
public void someInstanceMethod() {
System.out.println(outerClassField); // instance methods of non-static nested classes can access instance fields of the outer class
System.out.println(outerClassStaticField);
}

public static void someStaticMethod() {
System.out.println(outerClassStaticField);
}
}

public static class StaticNestedClass {
// code belonging to StaticNestedClass, e.g. fields, methods and constructors
public void someInstanceMethod() {
System.out.println(outerClassStaticField);
}

public static void someStaticMethod() {
System.out.println(outerClassStaticField);
}
}
}
public class OuterClass {
// code belonging to OuterClass, e.g. fields, methods and constructors
private String outerClassField = "some non-static field of the outer class";
private static String outerClassStaticField = "some static field of the outer class";

public class NormalNestedClass {
// code belonging to NormalNestedClass, e.g. fields, methods and constructors
public void someInstanceMethod() {
System.out.println(outerClassField); // instance methods of non-static nested classes can access instance fields of the outer class
System.out.println(outerClassStaticField);
}

public static void someStaticMethod() {
System.out.println(outerClassStaticField);
}
}

public static class StaticNestedClass {
// code belonging to StaticNestedClass, e.g. fields, methods and constructors
public void someInstanceMethod() {
System.out.println(outerClassStaticField);
}

public static void someStaticMethod() {
System.out.println(outerClassStaticField);
}
}
}
In that example, two nested classes are declared within OuterClass. While StaticNestedClass is marked with static, this is not the case with NormalNestedClass.
daysling
daysling3w ago
Nested classes can be accessed using the name (either the fully-qualified name or the simple name if it is imported or in the same package) of the outer class, a . and the name of the nested class. The constructor of static nested classes can be called in the same way but an object of the outer class is required for creating instances of non-static nested classes. For this, the object is written before the new operator. As the creation of instances of non-static nested classes requires an object of the outer class, that object is available within non-static methods (and constructor) of that (non-static) nested class.
OuterClass.StaticNestedClass.someStaticMethod();
OuterClass.StaticNestedClass snc = new OuterClass.StaticNestedClass();
snc.someInstanceMethod();

OuterClass outer = new OuterClass();
OuterClass.NormalNestedClass.someStaticMethod();
OuterClass.NormalNestedClass nnc = outer.new NormalNestedClass();
OuterClass.StaticNestedClass.someStaticMethod();
OuterClass.StaticNestedClass snc = new OuterClass.StaticNestedClass();
snc.someInstanceMethod();

OuterClass outer = new OuterClass();
OuterClass.NormalNestedClass.someStaticMethod();
OuterClass.NormalNestedClass nnc = outer.new NormalNestedClass();
The outer class can access private members of the nested classes and the nested class can also access private members within the enclosing class.
📖 Sample answer from dan1st
daysling
daysling3w ago
public class mainClass
{

int a = 42;

public mainClass()
{
printA();
}

public void printA()
{
System.out.println("a: " + a);
}

public static class nestedClass extends mainClass
{
public nestedClass()
{
printA();
}

public void printA()
{
a++;
System.out.println("inc a: " + a);
}
}
public class mainClass
{

int a = 42;

public mainClass()
{
printA();
}

public void printA()
{
System.out.println("a: " + a);
}

public static class nestedClass extends mainClass
{
public nestedClass()
{
printA();
}

public void printA()
{
a++;
System.out.println("inc a: " + a);
}
}
daysling
daysling3w ago
if you have a super class which gets implemented by other classes and if those other classes are static and inside of the super class then they're called nested classes
Submission from creepertv_1
daysling
daysling3w ago
In Java nested class means a class written inside an another class. Just like we can have functions or you can say method inside a class, we can also write a class inside another class that is what we call as nested class. It is used to group classes that are only used inside one class There are two types of nested classes 1. Static nested class 2. Non Static nested class Static Nested Class: We can create this with the use of "static" keyword. It doesn't need object of the outer class to be created. It means if you want use Static Nested Class in any another class then you can directly create object of that class without creating object of it's parent class Non Static Nested Class: It is normal nested class. If you want to create of this class then firstly you have to create object of it's parent class. It can access all variables and methods of it's parent class. Now we'll understand how the nested classes work behind the scenes: Firstly the compiler will create a separate .class file for every class you write in the program When a non static inner class is created, it holds a reference to the outer class object. This means the inner class constructor takes the outer class object as a hidden argument. This allows it to access all variables and methods of the outer class. And if talk about static inner class JVM treats it like a regular class just grouped inside another class. Based on memory A static nested class behaves like a normal class, so it’s more memory efficient because it doesn’t need to access outer class stuff. An inner class carries a reference to the outer class, so it uses more memory. But overall, unless you're creating millions of objects, this doesn't cause performance issues. The benefit of clean code usually outweighs the memory cost.
⭐ Submission from kherasam18
daysling
daysling3w ago
Nested classes are classes that are defined within another class. It's mostly used in arranging classes that are only relevant to one class (or their "outer class"). There are two types of nested class: i) Static nested class ii) Inner class Nested classes are scoped inside their outer class, and can have access modifiers (private, public, protected, ...) like any other normal classes. Two other important details about nested classes: - Static nested class cannot access outer classes fields (can access static fields), due to it's static property. This type of class can be initialised without initialising the outer class. - Non-static (Inner) nested class can access outer classes fields, this type of class cannot be initialised without initialising the outer class. Inner Nested Class Example:
public class Hello {
private String world;

public Hello(String test) {
this.world = test;
}

public class Life {
public String getWorld() {
return world;
}
}
}
public class Hello {
private String world;

public Hello(String test) {
this.world = test;
}

public class Life {
public String getWorld() {
return world;
}
}
}
Hello hello = new Hello("Earth");
Hello.Life life = hello.new Life();
System.out.println(life.getWorld()); // prints "Earth"
Hello hello = new Hello("Earth");
Hello.Life life = hello.new Life();
System.out.println(life.getWorld()); // prints "Earth"
Static Nested Class:
public class Outer {
private static String greeting = "Outer String";
private String instanceStr = "Instance String";
public static class Nested {
public void printGreeting() {
// Can access static members of the outer class
System.out.println(greeting);

// Cannot access instance members directly, this would raise a compile-time error.
// System.out.println(instanceVar);
}
}
}
public class Outer {
private static String greeting = "Outer String";
private String instanceStr = "Instance String";
public static class Nested {
public void printGreeting() {
// Can access static members of the outer class
System.out.println(greeting);

// Cannot access instance members directly, this would raise a compile-time error.
// System.out.println(instanceVar);
}
}
}
Outer.Nested nested = new Outer.Nested();
nested.printGreeting(); // Output: Outer String
Outer.Nested nested = new Outer.Nested();
nested.printGreeting(); // Output: Outer String
⭐ Submission from daysling

Did you find this page helpful?