Usage of Java internal classes and anonymous internal classes

Posted by sid666 on Sat, 18 May 2019 18:22:03 +0200

1. Internal Classes:

  **(1) Methods with the same name for internal classes**
    Internal classes can call methods of external classes, if methods of internal classes have the same name must be called in the format "OuterClass.this.MethodName()" (where OuterClass and MethodName are replaced with the actual external class name and methods; this is the keyword that represents a reference to the external class); methods of external classes can be called directly if methods of internal classes have no same name.
    However, peripheral classes cannot directly call privates of internal classes, and external classes cannot directly call privates of other classes.Note that the method used by an internal class directly by an external class has no relation to the permissions of the method and whether it is static or not, depending on whether the internal class has a method with the same name.
package innerclass;
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();// Use this to call methods of external classes when the internal class member method has the same name as the external class member method
		   outerMethod();// Execute methods of external classes when internal classes do not have methods with the same name
		}
		private void outerMethod() {
			System.out.println("It's Method of Innerclass");
		}
	}
}
     The output is:
It's Method of OuterClass
It's Method of Innerclass

(2) Variables accessing external classes by internal classes must be declared final
A local variable in a method that is released after the end of the method. The final guarantees that the variable always points to an object.
First, internal and external classes are actually at the same level, and internal classes are not destroyed as the method is executed because the definition is defined in the method.The problem is that if a variable in a method of an external class does not define final, then when the method of an external class finishes executing, the local variable must also be GC. However, before a method of an internal class finishes executing, the external variable that it refers to can no longer be found.If defined as final, java will copy this variable into an internal class as a member variable, so that since the value modified by final can never be changed, the memory area that this variable points to will not change.

  • Note that with JDK1.8, methods with internal classes are local variables that directly access methods with external classes and do not need to be declared final.
public class OuterClass {
	int num1 = 0;// Member variables
 
	private void outerMethod() {
		int num2 = 0;// Local variables within methods
		class Innerclass_1 {
			public void innerMethod() {
				System.out.println(num1);// A method of an internal class in a method that normally accesses member variables of an external class
				System.out.println(num2);// Prior to JDK1.8, methods of internal classes in methods could not directly access local variables of methods of external classes and must be declared final
			}
		}
	}
}
  If you use versions prior to JDK1.8, Eclipse will get the following error prompts:


(3) Instantiation of internal classes
Internal class instantiation is different from ordinary classes, which can be instantiated whenever needed, while internal classes must be instantiated after external classes have been instantiated, and relationships must be established with external classes.
So in a non-static method in an external class, you can instantiate an internal class object

private void outerMethod() {
		System.out.println("It's Method of OuterClass");
		Innerclass in = new Innerclass();//Is it possible to instantiate an internal class in the outerMethod method of an external class?
	}
 But in the static method, pay attention!!!!The new internal class cannot be directly in the static method, otherwise an error occurs:
 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 the class is instantiated, called by the class name, and then dynamic internal classes have not been instantiated yet. How to use it, you can never call something that does not exist.
 If you want 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 an internal class as static
		public void innerMethod() {
			System.out.println("It's Method of innerMethod");
 
		}
	}
 
}
 Of course, this is generally not a static approach, but rather recommended: x.new A(), where x is an 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();//How to use 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 division class Innerclass, which of course can be broken down as follows, so it's clear:
public static void main(String[] args) {
		OuterClass out = new OuterClass();//External Instances
		OuterClass.Innerclass in = out.new Innerclass();//External Instance. new External Class
		in.innerMethod();
	}

(4) When to use internal classes
Typically, an internal class inherits from a class or implements an interface, and its code operations create objects of its outer class.So you can think that internal classes provide some kind of advancement
A window into its outer class.
The most attractive reason to use internal classes is that each internal class can independently inherit from a (interface) implementation, so whether or not the outer class has inherited a (interface) fact
Now, it has no effect on internal classes.Some design and programming problems can be difficult to solve without the ability of internal classes to inherit multiple specific or abstract classes.From this angle
Internal classes complete multiple inheritance solutions.Interfaces solve some problems, while internal classes effectively implement "multiple inheritance".
(5) Instantiate an internal class in a static method example: (the internal class is placed in a static method)

package javatest2;
public class JavaTest2 {
	public static void main(String[] args) {
		class Boy implements Person {
			public void say() {// Anonymous internal class custom method say
				System.out.println("say Method Call");
			}
			@Override
			public void speak() {// Method talk to implement interface
				System.out.println("speak Method Call");
			}
		}
		Person per = new Boy();
		per.speak();// Callable
		per.say();// Cannot call
	}
}
interface Person {
	public void speak();
}
   Per.talk () is callable, but per.say() is not, because per is a Person object, to invoke a subclass method, you can force a downward transition to ((Boy) per.say(); or change directly to Boy per = new Boy();You can see that to invoke a custom method of an internal class, you must invoke it through an object of the internal class.So, how do I call an internal class custom method when an anonymous internal class doesn't even have a name?

(2) Anonymous internal classes
Anonymous internal classes, which are internal classes without names, can only be used once because they do not have names. They are usually used to simplify code writing, but there is a precondition to using anonymous internal classes: 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 internal class cannot be an abstract class, because the system immediately creates objects of the internal class when it creates the anonymous internal class.Therefore, defining anonymous internal classes as abstract classes is not allowed.
2) Anonymous internal classes do not equal defining constructors (constructors), because anonymous internal classes do not have class names, so constructors cannot be defined, but anonymous internal classes can define instance initialization blocks.
How can I tell if an anonymous class exists?You can't see the name, it just feels like the parent Newcomes out with an object, no anonymous class name.
Look at a pseudocode first

abstract class Father(){
....
}
public class Test{
   Father f1 = new Father(){ .... }  //Here's an anonymous inner class
}

Generally speaking, when a new object is opened, the parentheses should be followed by semicolons, which means the statement ends when the new object is exited.However, anonymous inner classes do not appear the same, parentheses are followed by braces, which are the concrete implementation of the new output object.Because we know that an abstract class cannot be directly new, we must have an implementation class before we can newout its implementation class.The pseudocode above indicates that newis the implementation class of Father, which is an anonymous internal class.
In fact, splitting the anonymous inner class above could be:

class SonOne extends Father{
  ...       //The code here is the same as the anonymous inner class above, and the code in braces is the same
}
public class Test{
   Father f1 = new SonOne() ;
}
 Let's start with an example of the use of anonymous internal classes:

Run result: eat something
 As you can see, we have implemented the methods in the abstract class Person directly in curly brackets so that we can omit the writing of a class.Anonymous internal classes can also be used on interfaces
public class JavaTest2 {
	public static void main(String[] args) {
		Person per = new Person() {
			public void say() {// Anonymous internal class custom method say
				System.out.println("say Method Call");
			}
			@Override
			public void speak() {// Method talk to implement interface
				System.out.println("speak Method Call");
			}
		};
		per.speak();// Callable
		per.say();// Error, cannot call
	}
}
 
interface Person {
	public void speak();
}
    Here per.talk() can be called normally, but per.say() cannot be called. Why?Note that Person per = new Person() creates a Person object, not an object of anonymous internal class.Actually, an anonymous internal class doesn't even have a name. How do you call its method from an instance object?However, methods and implementations that inherit from the parent class can be called normally. In this example, an anonymous internal class implements the Person speak method of the interface, so it can be called with the help of a Person object.
    If you really want to call the custom method say() of an anonymous internal class, there are also methods:
  (1) Similar to the use of the speak method, the say() method is declared in the Person interface and overridden in an anonymous internal class.
  (2) In fact, there is an anonymous object hidden in the anonymous internal class, through which the say() and speak() methods can be called directly; the code is modified as follows:
public class JavaTest2 {
	public static void main(String[] args) {
		new Person() {
			public void say() {// Anonymous internal class custom method say
				System.out.println("say Method Call");
			}
			@Override
			public void speak() {// Method talk to implement interface
				System.out.println("speak Method Call");
			}
		}.say();// Direct invocation of methods of anonymous internal classes
	}
}
interface Person {
	public void speak();
}

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

Topics: Java Eclipse Programming