Usage of Java inner classes and anonymous inner classes

Usage of Java inner classes and anonymous inner classes
1, Internal class:
Why are there inner classes?
1. If there is no method with the same name in the internal class, you can directly call the method of the external class.
2. If the internal class has a method with the same name, it must be called in the format of "OuterClass.this.MethodName() (* * where OuterClass and MethodName are replaced by the actual external class name and its method; this is the keyword, indicating the reference to the external class);
3. However, the outer class cannot directly call the private method of the inner class, and the outer class cannot directly call the private method of other classes. Note: the internal class directly uses the method of the external class, which has nothing to do with the permission of the method and whether it is static. It depends on whether the internal class has a method with the same name.

public class OuterClass {
        private void outerMethod() {
            System.out.println("It's Method of OuterClass");
        }
        public static void main(String[] args) {
            OuterClass t = new OuterClass();
            OuterClass.Innerclass in = t.new Innerclass();
            in.innerMethod();
        }
        class Innerclass {
            public void innerMethod() {
                OuterClass.this.outerMethod();// When the inner class member method has the same name as the outer class member method, use this to call the method of the outer class
                outerMethod();// Execute the method of the external class when the internal class does not have a method with the same name
            }
            private void outerMethod() {
                System.out.println("It's Method of Innerclass");
            }
        }
    }

Operation results:
It's Method of OuterClass
It's Method of Innerclass
(2) Variables for internal classes to access external classes must be declared final

  1. The local variable in the method will be released after the method is completed. final ensures that the variable always points to an object.
  2. First of all, the inner class and the outer class are actually at the same level. The inner class will not be destroyed as the method is executed because it is defined in the method
  3. The problem is that if the variable in the method of the external class does not define final, then when the method of the external class is executed, the local variable must also be GC. However, a method of the internal class has not been executed, and the external variable referenced by it can not be found at this time.
  4. If it is defined as final, java will copy this variable and build it into the internal class as a member variable. In this way, since the value modified by final cannot be changed, the memory area pointed to by this variable will not change.
 public class OuterClass {
	int num1 = 0;// Member variable
    private void outerMethod() {
		int num2 = 0;// Local variables within methods
		class Innerclass_1 {
			public void innerMethod() {
				System.out.println(num1);// The method of the inner class in the method can normally access the member variables of the outer class
				System.out.println(num2);// JDK1. Previously, the method of the inner class in the method cannot directly access the local variables of the method of the outer class, and must be declared as final
			}
		}
	}
}

If using jdk1 In versions before 8, Eclipse will display the following error prompt:

(3) Instantiation of inner classes
Internal class instantiation is different from ordinary classes. Ordinary classes can be instantiated whenever necessary, while internal classes can be instantiated only after the outer class is instantiated, and a relationship is established with the external class
Therefore, in the non static method in the external class, the internal class object can be instantiated

	private void outerMethod() {
		System.out.println("It's Method of OuterClass");
		Innerclass in = new Innerclass();//It is possible to instantiate an internal class in the outerMethod method of an external class
	}

But in the static method, you should pay attention!!!! The new inner class cannot be directly in the static method, otherwise an error will occur:
No enclosing instance of type OuterClass is accessible. Must qualify the allocation with an enclosing instance of type OuterClass (e.g. x.new A() where x is an instance of OuterClass).
This is because static methods can be used before class instantiation. They are called by class name. At this time, dynamic internal classes have not been instantiated. How to use them, you can't call something that doesn't exist.
If you want to create a new inner class in the Static method, you can declare the inner class as Static

public class OuterClass {
	private void outerMethod() {
		System.out.println("It's Method of OuterClass");
	}
 
	public static void main(String[] args) {
		Innerclass in = new Innerclass();
		in.innerMethod();
	}
 
	static class Innerclass {//Declare the inner class static
		public void innerMethod() {
			System.out.println("It's Method of innerMethod");
 
		}
	}
 
}

Of course, the static method is generally not used, but is recommended: x.new A(), where x is the instance of the external class OuterClass and A is the internal class Innerclass

package innerclass;
public class OuterClass {
	private void outerMethod() {
		System.out.println("It's Method of OuterClass");
	}
	public static void main(String[] args) {
		OuterClass.Innerclass in = new OuterClass().new Innerclass();//Using x.new A()
		in.innerMethod();
	}
	class Innerclass {
		public void innerMethod() {
			System.out.println("It's Method of innerMethod");
		}
	}
}

x.new A(), where x is an instance of the external class OuterClass and A is the class part class Innerclass. Of course, it can be split as follows, which is obvious:

public static void main(String[] args) {
  OuterClass out = new OuterClass();//External instance
  OuterClass.Innerclass in = out.new Innerclass();//External instance new external class
  in.innerMethod();
}

4) When to use inner classes
1. The inner class inherits from a class or implements an interface. The code operation of the inner class creates the object of its outer class. So you can think that the inner class provides some kind of advance
A window into its outer class.
2. The most attractive reason for using inner classes is that each inner class can independently inherit from one (Interface) implementation, so whether the outer class has inherited a (Interface) implementation or not has no impact on the inner class. Without the ability provided by internal classes to inherit multiple concrete or abstract classes, some design and programming problems are difficult to solve. From this perspective, inner classes make the solution of multiple inheritance complete. The interface solves some problems, and the internal class effectively implements "multiple inheritance".
(5) Example of instantiating an internal class in a static method: (the internal class is placed in the static method)

package javatest2;
public class JavaTest2 {
	public static void main(String[] args) {
		class Boy implements Person {
			public void say() {// Anonymous inner class custom method say
				System.out.println("say Method call");
			}
			@Override
			public void speak() {// Method of implementing interface
				System.out.println("speak Method call");
			}
		}
		Person per = new Boy();
		per.speak();// Callable
		per.say();// Cannot call
	}
}
interface Person {
	public void speak();
}

font color=per.speak() is callable, while per Say () cannot be called. At this time, because per is a Person object, if you want to call the methods of subclasses, you can force the downward transformation to: ((boy) per) say(); Or directly change to Boy per = new Boy();. It can be found that if you want to call the custom method of the internal class, you must call it through the object of the internal class. So, how can I call a custom method of an anonymous inner class without even a name?
(2) Anonymous inner class
1. Anonymous inner class is an inner class without a name because there is no name
2. Therefore, anonymous inner class can only be used once. It is usually used to simplify code writing, but there is another prerequisite for using anonymous inner class: you must inherit a parent class or implement an interface, but you can only inherit a parent class or implement an interface at most.
There are also two rules for anonymous inner classes:
1) An anonymous inner class cannot be an abstract class, because when the system creates an anonymous inner class, it will immediately create the object of the inner class. Therefore, anonymous inner classes are not allowed to be defined as abstract classes.
2) Anonymous inner classes do not define constructors (construction methods). Because anonymous inner classes do not have class names, constructors cannot be defined, but anonymous inner classes can define instance initialization blocks,
How to judge the existence of an anonymous class? I can't see the name. It feels like it's just an object in the parent class new. There is no name of the anonymous class.
Let's look at the pseudo code first

class SonOne extends Father{
  ...       //The code here is the same as the code in braces for the anonymous inner class above
}
public class Test{
   Father f1 = new SonOne() ;
}

Let's take a look at an example and experience the usage of anonymous inner classes:Running result: eat something
As you can see, we directly implement the methods in the abstract class Person in braces, so we can omit the writing of a class. Moreover, anonymous inner classes can also be used on interfaces

public class JavaTest2 {
	public static void main(String[] args) {
		Person per = new Person() {
			public void say() {// Anonymous inner class custom method say
				System.out.println("say Method call");
			}
			@Override
			public void speak() {// Method of implementing interface
				System.out.println("speak Method call");
			}
		};
		per.speak();// Callable
		per.say();// Error, cannot call
	}
}
 
interface Person {
	public void speak();
}

Here per Speak () can be called normally, but per Say () cannot be called. Why? Note that Person per = new Person() creates an object of Person, not an object of an anonymous inner class. In fact, the anonymous inner class doesn't even have a name. How can you call its method from an instance object? However, the methods inherited from the parent class and implemented methods can be called normally. In this example, the anonymous inner class implements the speak method of the interface Person, so it can be called with the help of the object of Person.
If you really want to call the custom method say() of the anonymous inner class, of course, there are also methods:
(1) Similar to the use of the speak method, first declare the say() method in the Person interface, and then override this method in the anonymous inner class.
(2) In fact, there is an anonymous object in the anonymous inner class, which can directly call the say() and speak() methods; The code is modified as follows:

public class JavaTest2 {
	public static void main(String[] args) {
		new Person() {
			public void say() {// Anonymous inner class custom method say
				System.out.println("say Method call");
			}
 
			@Override
			public void speak() {// Method of implementing interface
				System.out.println("speak Method call");
			}
		}.say();// Directly call methods of anonymous inner classes
	}
}
interface Person {
	public void speak();
}

https://blog.csdn.net/guyuealian/article/details/51981163

Added by Zangakat on Wed, 09 Feb 2022 22:50:09 +0200