Why is this an issue?

A non-static inner class has a reference to its outer class, and access to the outer class' fields and methods. That class reference makes the inner class larger and could cause the outer class instance to live in memory longer than necessary.

If the reference to the outer class isn’t used, it is more efficient to make the inner class static (also called nested). If the reference is used only in the class constructor, then explicitly pass a class reference to the constructor. If the inner class is anonymous, it will also be necessary to name it.

However, while a nested/static class would be more efficient, it’s worth noting that there are semantic differences between an inner class and a nested one:

How to fix it

There are two scenarios in which this rule will raise an issue:

  1. On an inner class: make it static.
  2. On a local class: extract it as a static inner class.

Code examples

Noncompliant code example

Inner classes that don’t use the outer class reference should be static.

public class Fruit {
  // ...

  public class Seed {  // Noncompliant; there's no use of the outer class reference so make it static
    int germinationDays = 0;
    public Seed(int germinationDays) {
      this.germinationDays = germinationDays;
    }
    public int getGerminationDays() {
      return germinationDays;
    }
  }
}

Compliant solution

public class Fruit {
  // ...

  public static class Seed {
    int germinationDays = 0;
    public Seed(int germinationDays) {
      this.germinationDays = germinationDays;
    }
    public int getGerminationDays() {
      return germinationDays;
    }
  }
}

Local classes that don’t use the outer class reference should be extracted as a static inner classes.

Noncompliant code example

public class Foo {
  public Foo() {
    class Bar { // Noncompliant
      void doSomething() {
        // ...
      }
    }
    new Bar().doSomething();
  }

  public void method() {
    class Baz { // Noncompliant
      void doSomething() {
        // ...
      }
    }
    new Baz().doSomething();
  }
}

Compliant solution

public class Foo {
  public Foo() {
    new Bar().doSomething();
  }

  public void method()  {
    new Baz().doSomething();
  }

  private static class Bar { // Compliant
    void doSomething() {
      // ...
    }
  }

  private static class Baz { // Compliant
    void doSomething() {
      // ...
    }
  }
}

Resources

Documentation

Articles & blog posts