In the actual project to see a very strange phenomenon, Java can be directly new interface, and then rudely in new to join the implementation code. Just like this. So the question is, isn't it strange that new objects have no actual classes as vectors?
Think about the output of the following code?
new Runnable() { @Override public void run() { System.out.println(this.getClass()); } }; x.run();
The actual answer is a class name that appears xxxx$1, which is the name given by the compiler.
Anonymous class
An anonymous class is the equivalent of creating a new instance of the class while defining the class. Let's take a look at the compilation results of anonymous classes.
The code for this class is as follows:
public class Test { public void test() { Runnable r = new Runnable(){ @Override public void run(){ System.out.println("hello"); } }; } }
Take a look at the results of the compilation, and the results are as follows by JAVAP backwards compiling test.class:
"Test.java" EnclosingMethod: #20.#21 // Test.test InnerClasses: #6; //class Test$1
A field called Enclosingmethod is found, indicating that the class is defined under the Test.test method. So now there's a question, what happens if there are two test methods?
It turns out that this comment is not very accurate and will actually contain the function signature. Take a look at the constant pool section, where #21 points to the function signature.
#21 = NameAndType #34:#16 // test:()V
Syntax for anonymous classes
Here is a simple example:
new Runnable() { public void run() { System.out.println("hello"); } };
An anonymous class consists of the following parts:
- New operator
- Runnable: Interface name. You can also fill in the name of the abstract class and the normal class.
- (): This parenthesis represents the argument list of the constructor. Since runnable is an interface with no constructors, filling in an empty parenthesis here means that there are no parameters.
- {...} : The code in the middle of the curly braces represents some structure inside this class. Here you can define the variable name, method. Just like the normal class.
Access rights
So what can anonymous internal classes access? According to the rules, you can access the following content:
- Access the fields inside the outer class.
- Cannot access local variables in the outer method. Unless the variable is final.
- If the name of the inner class is the same as the name that is accessible outside, the name is overwritten.
public class A { private int foo; public void test() { Runnable r = new Runnable() { System.out.println(foo); }; } }
Anonymous class can not have something:
1. You cannot define a static initialization code block (static Initializer). For example, the following code is not syntax-compliant:
public class A { public void test() { Runnable r = new Runnable() { static { System.out.println("hello"); } }; } }
2. You cannot define an interface within an anonymous class.
Like what:
public class A { public void test() { Runnable r = new Runnable() { public interface Hello { }; }; } }
The same as above, but also for the clarity of semantics. Interface can only be defined as static.
3. Constructors cannot be defined in an anonymous class.
public class A { public void test() { Runnable r = new Runnable() { public Runnable() { } }; } }
Because anonymous classes do not have names, constructors need to treat the class name as a constructor.
What you can include in an anonymous class is:
- Field
- Method
- Instance initialization code
- Local class
Why can't I define static initialization code
In fact, an inner class cannot define anything static.
Keyword: Inner class cannot has static declarations
Reference: Http://stackoverflow.com/questions/975134/why-cant-we-have-static-method-in-a-non-static-inner-class
There seems to be an explanation on StackOverflow as follows.
First look at an inner class.
public class A { public class B { } }
After it compiles, it becomes the following meaning:
public class A { public static class B { private final A parent; public B(A parent) { this.parent = parent; } } }
So, according to that, the inner class is a kind of syntactic sugar. When we define static variables, we create the following ambiguity. The following code does not look like a problem.
public class A { private int a; public class B { public static void test() { a = 1; } } }
But after compiling, the problem comes.
Publicclass a {private int A; public static class b {private final A parent; public B (A parent) {this.parent = parent;} public static void test () {parent.a = 1; //there is a syntax error}} }
So, in the final analysis, Java does not allow this ambiguous syntax to exist in order to maintain a clear syntax.
Talking about the anonymous class of Java