Part about inner classes , Learning more about . It is being revised and updated every day .
One 、 Member inner class
/** * You need to know two premises : * 1. The inner class of a member is a member of the outer class , The two of them have a very good relationship , Esteem, , share the same bed , Are the best brothers * So access rights and so on , It doesn't exist * * 2. The inner class object depends on the outer class object * reflection : * a, In a member method of a class inside a member , Is there a peripheral class object ? Yes * * The member method of the inner class of the member must be called by the object of the inner class of the member 【 understand 】 * Now that there are already objects with inner classes of members ,【 Why? ???】 So there must be peripheral class objects * * b, In the member method of the outer class , There is no inner class object ? No, * The inner class object depends on the outer class object , Although the objects of peripheral classes exist , But the objects of inner classes are not necessarily *========================================================================================== * - 【1】 Member inner class inner access outer class * 1, You can directly access , Regardless of access rights * 2, If you access the static members of a peripheral class , It is recommended to add the name of the peripheral class ( It's more readable ) * 3, The member methods of inner classes implicitly contain parameters EnclosedClazz.this, Represents the outer class object of the current inner class * You can use this to solve the problem of members with the same name of outer classes and inner classes * Of course It also implies a this, Represents the current inner class object * * This this It can be used to solve the problem that local variables and member variables have the same name * * - 【2】 Outer class access member inner class member * (1) In the normal member method of the outer class Create your own internal class objects manually You can use this object to access internal class members at will , Regardless of access rights * (2) If in a static method of a peripheral class Access internal class members . Two objects must be created Create an inner class object based on the outer class object * * - 【3】 External class access member internal class member * You must first create a peripheral class object Then create the inner class object * Be careful : External classes access internal classes Restricted by access * 1, If the inner class is private , An external class cannot create an object * 2, Even if you can create objects , Private members in inner classes are also not accessible * * - 【4】 The inner class of the member accesses the outer class member ( understand ) * > Access external class members in member inner classes , It's the same as accessing other class members in a normal class * * - Static members directly access the class name point * - Ordinary members need to create external class objects * - Are subject to access control */ public class OutsideClazz { // External class public static void main(String[] args) { // Create inner class objects // There are no peripheral class objects //EnclosedClazz enclosedClazz = new EnclosedClazz(); // //EnclosedClazz.InnerClazz innerClazz = enclosedClazz.new InnerClazz(); // // The following format Is a universal format for creating class objects inside members // Two - EnclosedClazz.InnerClazz innerClazz = new EnclosedClazz().new InnerClazz(); //System.out.println(innerClazz.a); } } class EnclosedClazz{ // Peripheral class // Member variables in peripheral classes int a; private int b = 10; static int c = 20; static final int D = 30; //(1) Member methods in peripheral classes public void test(){ // Access to internal class members must have internal class objects // Is there any ? Obviously not So create your own objects // A peripheral class object already exists here 【 Why? ???】 , use this instructions So you can directly create an internal class object InnerClazz innerClazz = new InnerClazz(); System.out.println(innerClazz.a);// Not restricted by access // Accessing static constants of inner classes , Just use the inner class name System.out.println(InnerClazz.D); //EnclosedClazz.InnerClazz innerClazz2 = new EnclosedClazz().new InnerClazz(); } //(2) In static methods of peripheral classes public static void testStatic(){ // Static methods of peripheral classes There is no object here ? There are no objects here Including peripheral class objects // So access the inner class members here Two objects must be created //1 Create peripheral class objects EnclosedClazz enclosedClazz = new EnclosedClazz(); //2 Create inner class objects InnerClazz innerClazz = enclosedClazz.new InnerClazz(); //3 The top can be two in one // After having an object , Access is the same Not subject to access control InnerClazz innerClazz1 = new EnclosedClazz().new InnerClazz(); //EnclosedClazz.InnerClazz innerClazz2 = new EnclosedClazz().new InnerClazz(); } class InnerClazz{ // Member inner class // reflection : What if the inner class has a static variable with the same name as the outer class ? In the wrong Member inner classes have no static variables //static int c = 200; // reflection : What if the inner class has a static constant with the same name as the outer class ? Just use the class name to distinguish // reflection : What if the inner class has a common variable with the same name as the outer class ? The member methods of ordinary classes contain this The ginseng Represents the current object // A parameter is also implied in the member method of the inner class of the member Represents the outer class object of the current inner class use EnclosedClazz.this Mark it static final int D = 300; private int a = 10; // Method dependent access to peripheral class members The member method of the inner class of the member must be called by the object of the inner class of the member 【 understand 】 public void testInner(){ System.out.println(EnclosedClazz.this.a);// Access the common member variable with the same name of the peripheral class System.out.println(b);// The inner class of a member is a member of the outer class , No access rights exist System.out.println(EnclosedClazz.c);// Access to static members of peripheral classes , It is recommended to add the name of the peripheral class ( It's more readable ) System.out.println(EnclosedClazz.D);// ditto here D For... In the outer class 30 System.out.println(this.D);// It also implies a this, Represents the current inner class object here D by 300 } } }
Two 、 Static inner class
/** * Premise : * 1, As long as it is an inner class , Peripheral classes are brothers , There are no access restrictions * 2, The outer class and inner class objects will not affect each other Do your own thing * * demand : Do not want to rely on peripheral classes , You don't want external classes to be able to access , Only static inner classes can be used * - 【1】 Static inner class internal access outer class * You must create a peripheral class object Static members recommend class name access Not subject to access control * * - 【2】 Peripheral classes access static inner class members * No matter what method , Create the inner class object directly Not restricted by access If it is a static member, it is recommended to use the class name to access * * - 【3】 External classes accessing static internal class members * Here, the static inner class is an independent class * The only difference You need the declared access permission restrictions of the class * grammar : * EnclosedClazz.InnerStaticClazz ecisc = new EnclosedClazz.InnerStaticClazz(); * * - 【4】 Static internal classes access external class members ( understand ) * > In static inner classes , Access external class members , It's the same as accessing other class members in a normal class * * - Static members , Class name points can be accessed directly * - Ordinary members need to create object access * - Controlled by access rights * */ public class OutsideClazz { // External class public static void main(String[] args) { // Create inner class objects // Can be created directly But it is different from ordinary classes // Need to tell the compiler Where is your inner class //EnclosedClazz.InnerClazz ic = new EnclosedClazz.InnerClazz(); //System.out.println(ic.privateVar); } } class EnclosedClazz { // Peripheral class int aEn; private int aEnPrivate = 10; static int b = 10; // Member method public void test(){ // There are no static inner class objects , Need to create // Not restricted by access } public static void testStatic(){ // Need to create peripheral class objects ? InnerClazz innerClazz = new InnerClazz(); } private static class InnerClazz { // Static inner class // Although this class adds static But don't think about static members here static Indicates that the inner class is independent // Define member variables int aEn; private int privateVar = 100; private static int b = 10; static int c = 20; static final int D = 30; // Define member methods public void test(){ // Access peripheral class members Peripheral class objects are required // reflection : There are no peripheral class objects ? // There are no peripheral class objects , You need to create a peripheral class object EnclosedClazz ec = new EnclosedClazz(); System.out.println(ec.aEn); // For peripheral classes, use peripheral class object methods System.out.println(ec.aEnPrivate); // reflection : Here, if the inner class and the outer class have the same name variables // For peripheral classes, use peripheral class object methods , Use your own this visit System.out.println(this.aEn); // use this Increase discrimination Use your own this visit System.out.println(InnerClazz.b);// Static members recommend class name access } public static void testStatic(){} } class InnerStatic{} }
3、 ... and 、 Local inner classes
public class Demo { // External class public static void main(String[] args) { //int a = 10; for (int i = 0; i < 1; i++) { class T{} } if (true){ class T{} } //switch } static { class S{} } } class EnclosedClazz { // Peripheral class public void test() { // Common member methods // Define local inner classes class InnerLocalClazz{ int a; private int b = 10; //Inner classes cannot have static declarations //static int c =100; static final int D = 100; // Static constants do not require class loading //Inner classes cannot have static declarations //static final Demo DEMO = new Demo();// Static reference type constants Only String Do not trigger class loading public void test(){} //public static void test2(){} } } } ===================================================================================== public class Demo { public static void main(String[] args) { } } class EnclosedClazz { // Peripheral class int a; private int b = 20; static int c = 10; public static void main(String[] args) { EnclosedClazz enclosedClazz = new EnclosedClazz(); enclosedClazz.test(); } public void test() { // Common member method // You can directly access peripheral class members , Because ordinary member methods imply this Point to current object So there are already objects // Have direct access to class InnerLocalClazz { // Local inner classes // Member methods of local inner classes public void test() { System.out.println(a); //0 System.out.println(b); //20 System.out.println(EnclosedClazz.c); //10 } } // Create an object in a method // Trigger class loading There is only one way Objects can only be created here InnerLocalClazz innerLocalClazz = new InnerLocalClazz(); // Call methods of local inner classes innerLocalClazz.test(); // Output here 3 It's worth } public static void testStatic() { // Static member methods class InnerLocalClazz{ // reflection : Can I directly access peripheral class members here ? // You can't , The reason is that the static method has no current object public void test(){ //System.out.println(b); } } } } Life cycle comparison of local internal class objects and method local variables Local inner class objects live longer than local variables jvm When will the copy of the play disappear : Live and die with your partner stay Java8 Before , In the local variables of this method final Must be added manually by the programmer , however 8 in the future ,Java Developers put this final Hidden to the bottom of the code public class Demo { // External class public static void main(String[] args) { EnclosedClazz enclosedClazz = new EnclosedClazz(); Father f = enclosedClazz.test(); // What is returned here is actually a InnerSon object // The parent class reference points to the subclass object Polymorphic calls f.testInner(); // There is no more a 了 // But you can still print a Value , explain jvm He did something for us secretly : // Put the local variables of the method a Into the object } } class EnclosedClazz { // Peripheral class public Father test() { // Define local inner classes Let it inherit Father int a = 10; // When test End of call a It's destroyed No more class InnerSon extends Father{ @Override public void testInner() { System.out.println("2"); //a = 20; //System.out.println(a); } } // Use... Again a // Create local inner class objects InnerSon is = new InnerSon(); // I just return this object as a return value return is; // A subclass can be regarded as a parent Upward transformation Automatically //is.test(); //2 } } class Father { public void testInner() { System.out.println("1"); } } ===================================================================================== The classic use of local inner classes /** * Write a method to return a concrete subclass of an interface or abstract class * * Return an interface implementation class with a local inner class Suitable for those who want to be lazy Do not want to write interface implementation classes suitable for * Suitable for Implementation classes that are used only once Or just want to call the method of the interface once * But for multiple calls , This method is not applicable * */ public class Demo { public static void main(String[] args) { // Classic writing calls I i = getIInstance(); i.test(); // High end writing of inner classes call I i2 = getIInstance2(); i2.test(); } public static I getIInstance(){ // Classical writing // First, use a class to implement this interface // Then create the object of this class return new IImpl(); // Anonymous object } // High end writing , Use local inner classes public static I getIInstance2(){ // Define local inner classes class IInner implements I{ @Override public void test() { System.out.println("222222"); } } // Create local inner class objects //IInner iInner = return new IInner(); } } interface I{ void test(); } class IImpl implements I{ @Override public void test() { System.out.println("1111111"); } }
Four 、 Anonymous inner class
/** * Anonymous inner class : It's anonymous ( Local ) Inner class , That is, anonymous inner classes are essentially local inner classes * Anonymous object : Objects without names * Anonymous inner class : There is no name ( Local ) Inner class * * Advantages and disadvantages of using anonymous inner classes : * 1, When we use a subclass object of a class or an interface only once , Use anonymous inner class , It will be a little more convenient * 2, If you need to access members of a subclass object more than once , Anonymous inner classes are troublesome . * 3, If you access a unique method in an anonymous subclass , Anonymous objects must be used to access * */ public class Demo { public static void main(String[] args) { // Old tricks : Create an implementation class for the interface I i = new IA(); i.test(); // New pattern : Local inner classes create interface implementation classes class InnerLocalClazz implements I{ @Override public void test() { System.out.println(" High end writing , Always so plain , boring !"); } } // Directly create local inner class objects InnerLocalClazz innerLocalClazz = new InnerLocalClazz(); innerLocalClazz.test(); // New patterns : On the basis of local inner classes , I don't even want your internal class , Directly create local inner class objects , That is, anonymous local class // grammar : Create objects directly : new Interfaces or classes (){}; // Mode one I i2 = new I() { @Override public void test() { System.out.println(" I am an anonymous inner class object test Method "); } public void test2(){ } };//new Plus the next piece is the object , You can use the parent class to receive it . Actually want to receive You can only use the parent class to receive i2.test(); //i2.test2(); Because look at the left , So you can't call methods unique to subclasses //((I) i2).test2(); // Because this subclass is anonymous , There's no way to force it // summary , This way, Killed You can't access the unique methods of subclasses // Mode two // The objects of the above anonymous inner classes can also not receive new I(){ @Override public void test() { System.out.println(" Receive without parent class "); }public void test2() { System.out.println(" Subclasses are unique "); } }.test2(); // There are two ways , What are the advantages and disadvantages of each // Mode 1: after receiving with an interface , This object has a reference , It can be used repeatedly , But the first method is to use the parent class reference to receive , In this way, the unique methods in subclasses are not used // Mode 2 does not receive , This object has no reference , It can only be used once , When you use it up, it becomes garbage . But way two You can call methods unique to subclasses // Mode one If both methods can be used Mode 2 is preferred Because the second way is easy // Create subclasses of classes with anonymous inner classes // grammar :new class (){}; new A(){ @Override public void test() { System.out.println(" I am an anonymous inner class subclass object of a normal class "); } }.test(); System.out.println(new AbstractA() { @Override public int test() { return 10; } }.test()); // This piece is equivalent to 10 So we can do 10 The operation of Such as assignment For example, calculation Like printing A a = new A() { }; // If it can be itself , What kind is it ? If it were a son , You can also use a parent class to receive Implicit inheritance } } interface I{ void test(); } class IA implements I{ @Override public void test() { System.out.println(" I am a IA I Implementation class of interface "); } } class A{ public void test(){} } abstract class AbstractA{ public abstract int test(); }