Inner classes are not very easy to understand, but to put it plainly, they are just a class that contains another class.

Just as a person is composed of body structures such as the brain, limbs, and organs, an inner class is equivalent to one of those organs, such as the heart: it also has its own properties and behaviors (blood, beating).

Obviously, a heart cannot be represented solely by properties or methods; it requires a class.

And the heart is inside the human body, just as an inner class is inside its outer class.

Example 1: Basic Structure of Inner Class

//外部类
class Out {
    private int age = 12;
     
    //内部类
    class In {
        public void print() {
            System.out.println(age);
        }
    }
}
 
public class Demo {
    public static void main(String[] args) {
        Out.In in = new Out().new In();
        in.print();
        //或者采用下种方式访问
        /*
        Out out = new Out();
        Out.In in = out.new In();
        in.print();
        */
    }
}

Output: 12

It is not hard to see from the above example that inner classes actually seriously damage good code structure, but why still use inner classes?

Because an inner class can freely use the member variables of the outer class (including private ones) without creating an object of the outer class; this is also the only advantage of inner classes.

Just like the heart can directly access the body's blood, rather than having a doctor draw blood.

After the program is compiled, two .class files are generated, namely Out.class and Out$In.class.

Here, $ represents the dot in Out.In in the above program.

Out.In in = new Out().new In()It can be used to create an object of the inner class. With this approach, there are two small points to note:

  • 1. The Out at the beginning is used to indicate which outer class the inner class object to be created belongs to.
  • 2. You must first have an object of the outer class before you can create an object of the inner class, because the purpose of the inner class is to access the member variables of the outer class.
class Out {
    private int age = 12;
     
    class In {
        private int age = 13;
        public void print() {
            int age = 14;
            System.out.println("局部变量:" + age);
            System.out.println("内部类变量:" + this.age);
            System.out.println("外部类变量:" + Out.this.age);
        }
    }
}
 
public class Demo {
    public static void main(String[] args) {
        Out.In in = new Out().new In();
        in.print();
    }
}

Output:

局部变量:14
内部类变量:13
外部类变量:12

From Example 1, it can be seen that when there are no member variables or local variables with the same name, the inner class directly accesses the member variables of the outer class without needing to specifyOut.this.propertyName。

Otherwise, local variables in the inner class will override the member variables of the outer class.

To access the inner class's own member variables, you can usethis.propertyName, and to access the outer class's member variables, you need to useOut.this.propertyName。

Example 3: Static Inner Class

class Out {
    private static int age = 12;
     
    static class In {
        public void print() {
            System.out.println(age);
        }
    }
}
 
public class Demo {
    public static void main(String[] args) {
        Out.In in = new Out.In();
        in.print();
    }
}

Output: 12

It can be seen that if you use static to make the inner class static, then the inner class can only access the static member variables of the outer class, which is a limitation.

Secondly, because the inner class is made static, Out.In can be treated as a whole, and you can directly create an object of the inner class with new (accessing static via the class name; it doesn't matter whether an outer class object is created).

Example 4: Private Inner Class/h3>
class Out {
    private int age = 12;
     
    private class In {
        public void print() {
            System.out.println(age);
        }
    }
    public void outPrint() {
        new In().print();
    }
}
 
public class Demo {
    public static void main(String[] args) {
        //此方法无效
        /*
        Out.In in = new Out().new In();
        in.print();
        */
        Out out = new Out();
        out.outPrint();
    }
}

Output: 12

If an inner class is intended to be operated on only by methods in the outer class, then you can declare the inner class as private.

In the above code, we must create an object of the In class inside the Out class to operate on it, and we can no longer useOut.In in = new Out().new In()to create an object of the inner class.

In other words, at this point, the inner class can be controlled only by the outer class.

Just like, my heart can only be controlled by my body; other people cannot directly access it.

Example 5: Method-Local Inner Class

class Out {
    private int age = 12;
 
    public void Print(final int x) {
        class In {
            public void inPrint() {
                System.out.println(x);
                System.out.println(age);
            }
        }
        new In().inPrint();
    }
}
 
public class Demo {
    public static void main(String[] args) {
        Out out = new Out();
        out.Print(3);
    }
}

Output:

3
12

In the above code, we moved the inner class into a method of the outer class, and then created an inner class object inside the outer class's method to call the inner class method.

If we need to pass parameters into the outer class's method at this point, then the method parameters of the outer class must be defined with final.

As for final, it has no special meaning here; it is just a formality.