1. The meaning of inner classes

Knowing the concept of inner classes, it’s a little strange how to use them, except when defining node classes with linked lists. Review to this knowledge point again, make a systematic summary

Inner class, literally, means “a class defined inside a class.” You can think of it as the engine of a car, which can only be used inside a car, but not for a train. The heart of the human body, which maintains blood circulation in the human body, gets cold when you take it out. These “internal parts”, which can only be used depending on the outside, are called internal classes.

The inner class is dependent on the outer class and exists, a class can not talk about inside and outside.

2. Introduction to internal classes

Inside and outside, access at will; For external use, you need an inner class object.

One feature of an inner class is the ability to access all fields of the outer class (including private permissions). At the same time, the outer class can access all the fields that the inner class modifies with access rights.

In the case of the human body, you can clearly feel your heart – it knows if you’re alive or not, even if it’s still beating. People did not, the heart will rest; My heart stops beating and I get cold.

The commonality of inner classes

(1). The inner class is a separate class defined inside the class. After compilation, the inner class will be compiled into a separate.class file, but preceded by the outer class name and $symbol.

(2). Inner classes also need to be instantiated to access them

(3). The inner class can only access the static member variables of the outer class.

(4). An outer class cannot access a member of an inner class directly, but can access it through an inner class object. The inner class is a member of the outer class, so the inner class has free access to the member variables of the outer class, whether private or not. (There are explanations behind, detailed source code compilation and explanation refer to the end of the link article)

3. Classification of inner classes

I. Member inner classes

Define a class inside a class that cannot contain static variables or methods.

There are two ways to use member inner classes:

Access the external class name directly. Inner class name Object name = new Outer class name ().new Inner class name ();

Create inner class objects directly to access inner classes

public class BodyII { private String name; // Inner class Heart {// Inner class method public voidbeat() {
           System.out.println("Inner class method"); }} // External class method public voidbreathe() {
        new Heart().beat();
        System.out.println("External class method"); } public static void main(String[] args) {// Create an inner class object directly to access the outer class name. Inner class name Object name = new Outer class name ().new Inner class name (); BodyII.Heart body = new BodyII().new Heart(); body.beat(); }}Copy the code

Inner class method

Indirect access

In methods of outer classes, use inner classes; Call inner class methods indirectly with methods of the outer class

public class BodyI { private String name; // Inner class Heart {// Inner class method public voidbeat() {
           System.out.println("Inner class method"); }} // External class method public voidbreathe() {
        new Heart().beat();
        System.out.println("External class method"); } public static void main(String[] args) { BodyI body = new BodyI(); Breathe (); breathe(); breathe(); breathe(); }}Copy the code

Inner class method Outer class method

Access to variables with inner class duplication In classes that have inner classes, member variable duplication may occur

A member variable of an external class

A member variable of an inner class

A local variable

In an inner class, when accessing a named member variable of an outer class:

External class name. This. External class member variable name

Public class Outer {// The name of the Outer class. Int num = 10; public class Inner { int num = 20; public voidinnerMethod() { int num = 30; System.out.println(num); // Local variable, nearest rule system.out.println (this.num); // Inner class member variable system.out.println (Outer.this.num); }} public static void main(String[] args) {Outer.Inner obj = new Outer().new Inner(); obj.innerMethod(); }}Copy the code

The results

30 20 10

II. Static inner classes

We know that a static member of a class exists independently of any object of the class, so as long as we have access, we can pass the class name. The static member name is used to access this static member, without the need to invoke it by instantiating the object.

Similarly, a static inner class exists as a static member of an external class. Creating a static inner class object of a class does not depend on its external class object.

Let’s start with a simple example:

The results

Access the external class static member variable Hello World

Summary of inner class code

class Out {

    private static int i = 10;
    private int j = 20;

    public static void outer_f1() {
        System.out.println("Accessing static members of an external class");
    }

    public void outer_f2() {
        System.err.println("Cannot access a non-static member of an external class"); } private static class Inner {static int inner_i = 100; int inner_j = 200; // A static inner class can access only static members (including static variables and static methods) of an external classinner_f1() {
            System.out.println("Outer.i: " + i);
            outer_f1();
        }

        void inner_f2() {// Static inner classes cannot access non-static members of external classes (including non-static variables and non-static methods)}} public voidouter_f3() {// The outer class accesses the static member of the inner class: the inner class. Static member System.out.println("Inner.i: "+ Inner.inner_i); Inner.inner_f1(); Inner_f2 (); new Inner().inner_f2(); } } public class Outerclass { public static void main(String[] args) { new Out().outer_f3(); }}Copy the code

The results

Inner. I: 100 Outer. I: 10 Accesses static members of the Outer class

As you can see, we can treat a static inner class as a static member of an external class, without relying on the external class object to create its object. (Accessing a static member of a class does not depend on the object of the class, because it is independent of the objects of all classes.)

But, in a static inner class cannot access external non-static member of the class, because the external class non-static member belongs to each of the outer class object, which itself is the independent external static inner class class objects exist, so the static inner class cannot access external class non-static member, and outside classes can still access all of the static inner class object access members, This is no different from ordinary inner classes.

conclusion

A static inner class can access only the static members of the outer class, not the ordinary members

An external class can access a static member of an inner class: the inner class. Static members

An external class accesses a non-static member of an inner class: instantiate the inner class

III. Local interior class

Local inner classes, like local methods and variables, are defined in methods, so local inner classes are defined in methods.

If a class is defined inside a method, it is a local inner class.

Local meaning: it can only be used by the current method, not outside the method.

public class Outer {
    public void methodOuter() {class Inner {// int num = 10; public voidmethodInner() {
                System.out.println("Call local inner class:" + num);
            }
        }
        Inner in= new Inner(); in.methodInner(); } public static void main(String[] args) { Outer out = new Outer(); out.methodOuter(); }}Copy the code

Running results:

Call the local inner class: 10

Permission modifier for an inner class

Permission modifier: public > protected > (default) > private

When defining an inner class, the permission modifier rule is:

External class: Public/(default)

Member inner class: public > protected > (default) > private

Local inner class :(default) do not write by default

Final problems with local inner classes

Local inner class. If you want to access the local variable of the method, the local variable must be valid final.

Why does the member variable num have to be final?

A: Because of life cycle problems, to ensure that num is still available to objects in the inner class after the member variable is destroyed, a copy of num from stack memory is required to the constant pool.

The object that comes out of new is in the heap

Local variables follow the method, in stack memory

Once the method is out of the stack, the local variable disappears immediately

But new objects persist in the heap until the garbage collection is gone

IV. Anonymous inner classes

If the interface implementation class (or subclass) needs to be used only once, then the class definition can be omitted and anonymous inner class is used instead.

Anonymous inner class definition:

For format new interface name () {}; Go on doing STH.

New represents the action of creating an object

The interface name is the interface that the anonymous inner class needs to implement

{}; That’s what anonymous inner classes are all about

Anonymous inner classes are local inner classes without a class name

The use of anonymous inner classes

Anonymous inner classes are frequently used, most commonly in interface implementation.

Typically, we define the interface first, then implement it, and finally instantiate the implementation class to use it.

For example, for a login function, we would write:

public interface Userdao { void login(User user); } public class UserdaoImpl implements UserDao {public void login(User User); { System.out.println("Query User Records"); }}... Userdao dao = new UserDaoImpl(); dao.login();Copy the code

Writing each function module like this is independent, the logical structure of the code is clearer, and it is convenient for us to use interfaces and implementation classes many times.

However, we can use anonymous inner classes when the implementation class will only be used once, and the definition above is a bit cumbersome and requires an implementation class with an interface to be instantiated.

【 For example 】

When we define the implementation of the list, we will write a list iterator to iterate over each node of the list, implementing the Iterable interface

However, we only use this class once, eventually iterating through the list, so we implement the Iterable interface as an anonymous inner class.

public class LinkList<T> implements Iterable<T> { ...... Iterator is an interface that uses an inner class to instantiate * @return
     */
    @Override
    public Iterator iterator() {

        return new Iterator() {

            private Node node = head;

            @Override
            public boolean hasNext() {
                returnnode.next ! = null; } @Override public Objectnext() {// point to the first data storage node node = node.next;returnnode.data; }}; }}Copy the code

The anonymous inner class seems to be written so stealthily that it is not easy to see. In fact, the way to identify is very simple, if the code block has; That’s a good judgment call.

{};

Anonymous inner class summary

Anonymous objects:

Anonymous inner classes implement methods. Anonymous object to call a method!

Anonymous inner classes can only be used once during object creation.

If you want to create an object multiple times, and the content of the class is the same, then you must use a separately defined implementation class to create an anonymous object that can only be called once when the method is called.

If you want to call the same object multiple times, you must give the object a name. Anonymous inner classes omit implementation class/subclass name, but anonymous objects omit object name.

Note: Anonymous inner classes and anonymous objects are not the same thing!!

Q: Why can an inner class access a member of an outer class

Understand why inner classes can access members of outer classes in Java

The compiler automatically adds a member variable to the inner class. This member variable is of the same type as the outer class. This member variable is a reference to the object of the outer class.

The compiler automatically adds a parameter to the constructor of the inner class. The parameter is of the type of the outer class and is used inside the constructor to assign values to the added member variables.

When an inner class’s constructor is called to initialize an inner class object, a reference to the outer class is passed in by default

Q: Why can’t member inner classes contain static variables and methods?

The difference between classes and objects is that static properties do not depend on objects, so access changes do not depend on whether an object is currently alive.

The inner class can be thought of as a member variable of the outer class. To access the inner class, you must first instantiate the outer class and then access the inner class through the outer class. As long as a member variable is dependent on a concrete object, declaring static properties in a non-static inner class would break this logic, so the Java language doesn’t semantically allow us to do that.

If you don’t understand anything, leave a comment below and give it a thumbs up