问题
What is happening while instantiating class Person? What is an anonymous inner class?
abstract class Person {
abstract void eat();
}
class TestAnonymousInner {
public static void main(String args[]) {
Person p = new Person() {
void eat() {
System.out.println("nice fruits");
} // what happens here?
};
p.eat();
}
}
回答1:
Anonymous classes are really just syntactic sugar.
Since Person
is abstract, you can't directly create an instance of Person
. You must create an instance of a class that inherits Person
. That's how abstract classes are designed.
However, sometimes it's quite inconvenient to create a subclass of Person
when you want to use this class. You have to write something like this:
class MyClass {
public static void main(String args[]) {
Person p = new PersonSubclass();
p.eat();
}
}
class PersonSubclass extends Person {
void eat() {
System.out.println("nice fruits");
}
}
People reading your code has to find the declaration of PersonSubclass
in order to know what the code does.
But let's think about the root of the problem: the reason why you can't create an instance of Person
is because eat
does not have a method body. So if you create a method body for eat
, you can "kind of" create an instance of Person
. And this is what anonymous classes are. They allow you to create instances of abstract classes/interfaces just by writing method bodies. That's why the above code can just be written like this:
public static void main(String args[]) {
Person p = new Person() {
void eat() {
System.out.println("nice fruits");
}
};
p.eat();
}
It's much shorter and easier to read, isn't it?
What is really happening here then?
The compiler creates a subclass of Person
for you, as an inner class of the enclosing class. And in that subclass, there is your method body for eat
. The inner class is given a very special name (I can't remember what though) so that normal code can't access it.
P.S. In Java 8, lambdas are introduced. They are again syntactic sugar for interfaces with only one method. This does not work with abstract classes though.
回答2:
Person
is abstract
so you can't instantiate it ; but by injecting an implementation for the abstract
method during the instantiation, Person
become "instantiatable" ; and at the end an invocation of eat()
is done and the result will be : eat()
=> nice fruits
回答3:
Actually Anonymous Inner class is the way to declare and instantiate a class at same time. They are as any other classes except do not having a name. Whenever you declare an Inner class whatever it is Anonymous or not, Compiler creates an internal class for that class. Like what is happening here is, Compiler creates a internal class like below
static class TestAnonymousInner$1 extends Person
{
TestAnonymousInner$1(){}
void eat()
{
System.out.println("nice fruits");
}
}
you can see this is just like any other local classes. But as Person
is an abstract
class, it cannot be instantiated without extending. Thats why compiler created internal class is of type extends Person
来源:https://stackoverflow.com/questions/43492238/what-is-happening-while-instantiating-an-abstract-class-what-is-an-anonymous-in