java - detailed explanation of internal classes

catalogue

  Inner class concept

1. Member inner class

(associated with member variables and member methods, the location of the internal class is at the same level as the member of the class)

2. Static inner class (think of static members and use static modification)

  3. Local inner class (associated with local variables, located in the member methods of the outer class)

4. Anonymous inner class (associated with anonymous objects and anonymous arrays, the inner class has no name and needs a class or interface)

Inner class concept

Definition: define a class inside other classes. This class is called an inner class (nested class).

Classification: it is divided into member internal class, static internal class, local internal class and anonymous internal class according to its location and form.

1. Member inner class

(associated with member variables and member methods, the location of the internal class is at the same level as the member of the class)

// External class
class OuterClass01 {

// Member inner class

class InnerClass01 {



}

}

Look at the generated bytecode files. There are two: OuterClass01.class and OuterClass01$InnerClass01.class,

Member internal class bytecode Name: external class name $member internal class name. Class.

Creation method:

1.1 how to create a member internal class object 1: by calling the constructor of the member internal class.

Format: external class name. Internal class name member internal class object name = external class object. new internal class constructor ();

Method 1. OuterClass01.InnerClass01 innerClass01 = (new OuterClass01()).new InnerClass01();

Method 2. OuterClass01.InnerClass01 innerClass01 = new OuterClass01().new InnerClass01();

package cn.temptation;

public class Test {

    public static void main(String[] args) {

    //Create external class object

        OuterClass01 outerClass01 = new OuterClass01();

        OuterClass01.InnerClass01 innerClass01 = outerClass01.new InnerClass01();

        System.out.println(innerClass01);

        // cn.temptation.OuterClass01$InnerClass01@15db9742

    }

}

  Understanding: OuterClass01.InnerClass01 innerClass01 = outerClass01.new InnerClass01();

It can be understood as: OuterClass01.InnerClass01 innerClass01 = outerClass01.(new InnerClass01()); (the syntax of this method is wrong, and it is only written for convenience of understanding.) that is, call the members of the class through the object name. The internal class of the member here is also a member of the external class, so consider using the object name. Call in this way, and what you want to get here is the internal class object of the member, Therefore, get the member inner class object through the constructor of the new member inner class

1.2 how to create internal class objects of members 2:

By calling the member method of the external class where the member's internal class is located, the object of the member's internal class is created in the external class

// External class
class OuterClass02 {

// Member variable

private InnerClass02 innerClass02;

// Member method

// Multi instance creation method (inside the class, member methods can access members)

public InnerClass02 getInnerClass02() {

return new InnerClass02();

}


// Singleton creation method (lazy, inside the class, member methods can access members)

public InnerClass02 getInstance() {

if (innerClass02 == null) {

innerClass02 = new InnerClass02();

}


return innerClass02;

}


// Member inner class

class InnerClass02 {

// Set constructor private

private InnerClass02() {


}

}

}
package cn.temptation;



public class Test {

    public static void main(String[] args) {

        OuterClass02 outerClass02 = new OuterClass02();



        // Writing method of creating class objects inside members (multiple cases)

        OuterClass02.InnerClass02 innerClass02 = outerClass02.getInnerClass02();

        System.out.println(innerClass02);  

        //cn.temptation.OuterClass02$InnerClass02@15db9742

        OuterClass02.InnerClass02 innerClass02Ex = outerClass02.getInnerClass02();

        System.out.println(innerClass02Ex);  

        //cn.temptation.OuterClass02$InnerClass02@6d06d69c


        System.out.println("----------------------");


        // Writing method of creating class objects inside members (singleton)

        OuterClass02.InnerClass02 innerClass02Demo = outerClass02.getInstance();

        System.out.println(innerClass02Demo);      

       //cn.temptation.OuterClass02$InnerClass02@7852e922

        OuterClass02.InnerClass02 innerClass02DemoEx = outerClass02.getInstance();

        System.out.println(innerClass02DemoEx);          

       //cn.temptation.OuterClass02$InnerClass02@7852e922

    }

}

characteristic:  

1. The inner class of a member can directly access the non static member variables and static member variables of its external class

// External class

class OuterClass04 {

// Non static member variables

public int i = 2;

private int j = 3;

// Static member variables

public static int x = 4;

private static int y = 5;



// Member inner class

class InnerClass04 {

// Member method

public void showByInner() {

// The internal class of a member can access the non static member variables of its external class (whether public or private)

System.out.println(i);

System.out.println(j);

// The internal class of a member can access the static member variables of its external class (whether public or private)

System.out.println(x);

System.out.println(y);

}

}

When the external class and internal class member variables are the same:   The obtained variable value adopts the proximity principle

// External class

class OuterClass05 {

// Non static member variables

public int i = 2;

// The member variable of the outer class has the same name as the member variable of the inner class

public int k = 4;

// Static member variables

public static int x = 6;

public static int z = 8;



// Member inner class

class InnerClass05 {

// Non static member variables

public int j = 3;

// The member variable of the outer class has the same name as the member variable of the inner class

public int k = 5;

// Static member variable: define static member variable in non static member inner class, syntax error

// Syntax error: the field y cannot be declared static in a non static inner type, less initialized with a constant expression

// public static int y = 7;

// Syntax error: the field Z cannot be declared static in a non static inner type, less initialized with a constant expression

// public static int z = 9;



// Member method

public void showByInner() {

System.out.println(i); // 2

System.out.println(j); // 3

System.out.println(k); // 5 --- member variables of internal classes (proximity principle)

System.out.println(this.k); // 5 --- member variable of the inner class (this refers to the inner class object of the current member)

System.out.println(this); // cn.temptation.OuterClass05$InnerClass05@15db9742



// Question: what if you want to use the member variable with the same name of the external class in the member method of the internal class of the member?

// Idea 1. Consider creating an external class object, and then obtain it through the external class object. Member variable

System.out.println((new OuterClass05()).k); // 4 --- member variable of external class

// Train of thought 2. Consider whether the external class object is created when the internal class object of a member is created, and if so, what kind of access form it is

// A: created. The access form is external class name. this

System.out.println(OuterClass05.this); // cn.temptation.OuterClass05@6d06d69c

System.out.println(OuterClass05.this.k); // 4 --- member variable of external class



// Access the static member variable of the external class directly through the external class class name. Static member variable

System.out.println(OuterClass05.x); // 6

System.out.println(OuterClass05.z); // 8

}

}

2. A member method of a member's inner class can access all member methods of its outer class (whether public or static)

// External class

class OuterClass06 {

// Member method

public void method1() {

System.out.println("Public non static member methods of external classes");

}



private void method2() {

System.out.println("Private non static member method of external class");

}



public static void method3() {

System.out.println("Public static member methods of external classes");

}



private static void method4() {

System.out.println("Private static member method of external class");

}



// Member inner class

class InnerClass06 {

// Member method

public void showByInner() {

// A member method of a member's inner class can access all member methods of its outer class (whether public or static)

method1();

method2();

method3();

method4();

}

}

2. Static inner class (think of static members and use static modification)

// External class

class OuterClass08 {

// Static inner class

static class InnerClass08 {



}

}

Look at the generated bytecode files. There are two: OuterClass08.class and OuterClass08$InnerClass08.class. The static internal class bytecode name is: external class name $static internal class name. Class.

Creation method:

Format: external class name. Internal class name    Static internal class object name  =   new external class name. Static internal class constructor ();

package cn.temptation;



public class Test {

    public static void main(String[] args) {

        OuterClass08.InnerClass08 innerClass08 = new OuterClass08.InnerClass08();

        System.out.println(innerClass08);

        // cn.temptation.OuterClass08$InnerClass08@15db9742



    }

}

  characteristic:

1. In a static inner class, either static member methods or non static member methods can only access the static member variables of the outer class

// External class

class OuterClass09 {

// Non static member variables

public int i = 2;

private int j = 3;

// Static member variables

public static int x = 4;

private static int y = 5;



// Static inner class

static class InnerClass09 {

// Non static member method

public void showByInner() {

// A non static member method in a static inner class cannot access a non static member variable of its outer class

// Cannot make a static reference to the non-static field i

// System.out.println(i);

// Cannot make a static reference to the non-static field j

// System.out.println(j);



// A non static member method in a static inner class can access the static member variables of its outer class

System.out.println(x); // 4

System.out.println(y); // 5

}



// Static member method

public static void showByInnerStatic() {

// A static member method in a static inner class cannot access non static member variables of the external class in which it is located

// Cannot make a static reference to the non-static field i

// System.out.println(i);

// Cannot make a static reference to the non-static field j

// System.out.println(j);



System.out.println(x); // 4

System.out.println(y); // 5

}

}

  2. In a static inner class, either static or non static member methods can only access the static member methods of the external class

// External class

class OuterClass10 {

// Member method

public void method1() {

System.out.println("Public non static member methods of external classes");

}



private void method2() {

System.out.println("Private non static member method of external class");

}



public static void method3() {

System.out.println("Public static member methods of external classes");

}



private static void method4() {

System.out.println("Private static member method of external class");

}



// Static inner class

static class InnerClass10 {

// Non static member method

public void showByInner() {

// Syntax error: cannot make a static reference to the non static method method1() from the type outerclass10

// method1();

// Syntax error: cannot make a static reference to the non static method method2() from the type outerclass10

// method2();



method3();

method4();

}



// Static member method

public static void showByInnerStatic() {

// Syntax error: cannot make a static reference to the non static method method1() from the type outerclass10

// method1();

// Syntax error: cannot make a static reference to the non static method method2() from the type outerclass10

// method2();



method3();

method4();

}

}

  3. Local inner class (associated with local variables, located in the member methods of the outer class)

// External class

class OuterClass12 {

// Member method

public Object showByOuter() {

// Local inner class

class InnerClass12 {



}



// Instantiate a local inner class in a member method of an outer class

InnerClass12 innerClass12 = new InnerClass12();

return innerClass12;

}

}

Look at the generated bytecode file. There are two: OuterClass12.class and OuterClass12 InnerClass12.class. The bytecode name of the local internal class is: external class name $number and local internal class name. Class. The number here is the corresponding number of the local internal class type. The number of the same local internal class starts from 1.

Note: in the member method of the same external class, it is not allowed to create multiple local internal classes with the same name; Local internal classes with the same name can be defined in different member methods in the external class. These local internal classes can have the same name and different members.

The member method of the local inner class accesses the local variables defined in the member method of the external class where the local inner class is located. The local variables can be modified with or without final modification. However, whether final modification is used or not, the member methods of the local inner class can only be accessed (read) and cannot be set (assigned)

Creation method:

//A local inner class object created in a member method can only be returned through the member method of the outer class in which it is located

OuterClass12 outerClass12 = new OuterClass12();

System.out.println(outerClass12.showByOuter());    

  characteristic

1. Non static member variables and static member variables of the external class can be accessed directly in the local internal class

// External class

class OuterClass13 {

// Non static member variables

public int i = 2;

private int j = 3;

// A member variable with the same name as an external class and a local internal class

public int k = 4;

// Static member variables

public static int x = 6;

private static int y = 7;

public static int z = 8;



// Member method

public void showByOuter() {

// Local inner class

class InnerClass13 {

// Non static member variables

// A member variable with the same name as an external class and a local internal class

public int k = 5;

// Static member variables

// Syntax error: the field Z cannot be declared static in a non static inner type, less initialized with a constant expression

// public static int z = 8;



// Member method

public void showByInner() {

// The local inner class can access the non static member variables of its external class (whether public or private)

System.out.println(i); // 2

System.out.println(j); // 3

// The local inner class can access the static member variables of its external class (whether public or private)

System.out.println(x); // 6

System.out.println(y); // 7



System.out.println(k); // 5 --- non static member variables of local internal classes (proximity principle)

System.out.println(this.k); // 5 --- non static member variable of local inner class (this refers to local inner class object)

System.out.println(this); // cn.temptation.OuterClass13$1InnerClass13@15db9742



System.out.println(OuterClass13.this); // cn.temptation.OuterClass13@6d06d69c

System.out.println(OuterClass13.this.k); // 4 --- non static member variable of external class



System.out.println(OuterClass13.z); // 8

}

}



// Instantiate a local inner class object in a member method of an outer class

InnerClass13 innerClass13 = new InnerClass13();

innerClass13.showByInner();

}

  2. In the local inner class, you can directly access the non static member methods and static member methods of the external class

// External class

class OuterClass14 {

// Member method

public void method1() {

System.out.println("Public non static member methods of external classes");

}



private void method2() {

System.out.println("Private non static member method of external class");

}



public static void method3() {

System.out.println("Public static member methods of external classes");

}



private static void method4() {

System.out.println("Private static member method of external class");

}



public void showByOuter() {

// Local inner class

class InnerClass14 {

// Member method

public void showByInner() {

// A local inner class is accessible to the non static member methods of its outer class (whether public or private)

method1();

method2();

// A local inner class is accessible to the static member methods of its outer class (whether public or private)

method3();

method4();

}

}



// Instantiate a local inner class object in a member method of an outer class

InnerClass14 innerClass14 = new InnerClass14();

innerClass14.showByInner();

}

4. Anonymous inner class (associated with anonymous objects and anonymous arrays, the inner class has no name and needs a class or interface)

// Define interface

interface Foo {

public abstract void show();

}



// Implementation class of interface

class FooImpl implements Foo {

@Override

public void show() {

System.out.println("The member method of the implementation class of the interface");

}

}



// External class

class OuterClass18 {

// Member method

public Foo showByOuter() {

// Polymorphic writing method, create interface type variables, receive interface implementation class type objects, and return

// Foo foo = new FooImpl();

// return foo;



// For the modification of the above writing method, the writing method of anonymous object

// return new FooImpl();



// Anonymous inner class that implements the Foo interface (located in a location similar to the local inner class)

return new Foo() {

@Override

public void show() {

System.out.println("Implements the anonymous inner class of the interface");

}

};


}

Look at the generated bytecode files. There are two: OuterClass18.class and OuterClass18 .class

Anonymous internal class bytecode Name: external class name $number. Class

Creation method

By calling the member method of the external class where the anonymous inner class is located

package cn.temptation;



public class Test {

    public static void main(String[] args) {

        OuterClass18 outerClass18 = new OuterClass18();

        // Define variables of interface type to receive the return of anonymous inner class objects

        Foo foo = outerClass18.showByOuter();

        System.out.println(foo);

        // cn.temptation.OuterClass18$1@15db9742

        foo.show(); // This statement actually calls the member method of the interface implementation object (anonymous inner class object)

    }

}

characteristic

1. The anonymous inner class does not have a constructor, and the user cannot create a constructor, but in fact, the JDK generates a constructor for the anonymous inner class

2. The member method of an anonymous inner class can access the member variables of its external class (whether public or private, static or non-static). The same variable is also the proximity principle

// Interface

interface Sample {

public abstract void show();

}



// External class

class OuterClass22 {

// Member variable

public int i = 2;

private int j = 3;

int k = 6;

public static int x = 4;

private static int y = 5;



// Member method

public void showByOuter() {

// local variable

int k = 7;



// Anonymous Inner Class 

(new Sample() {

@Override

public void show() {

System.out.println(i); // 2

System.out.println(j); // 3

System.out.println(x); // 4

System.out.println(y); // 5



System.out.println(k); // 7 --- local variable (proximity principle)

// Syntax error: k cannot be resolved or is not a field

// System.out.println(this.k);

System.out.println(this); // cn.temptation.OuterClass22$1@15db9742

System.out.println(OuterClass22.this); // cn.temptation.OuterClass22@6d06d69c

System.out.println(OuterClass22.this.k);// 6

}

}).show();

}

Tags: Java

Posted on Sun, 10 Oct 2021 19:00:18 -0400 by magaly