Today I learned about inner classes and learned that inner classes can hold this of outer classes, so that OuterClass.this.medthod() can be used in inner classes to reference the corresponding outer class methods. But I wrote the code and it can run. However, I don't understand the calling logic very well. I hope you can enlighten me!
public class test {
public void report(){
System.out.println("I'm invoked!");
}
public void perform(){
new Speaker().handleAction(new Action(){
@Override
public void action() {
report();//???为什么能调用report??
}
});
}
public static void main(String[] args) {
new test().perform();//测试代码
}
}
class Speaker{
void handleAction(Action act){
act.action();
}
}
interface Action{
void action();
}
The design is like this. The test object calls the perform method, which creates a new Speaker anonymous class object. The object calls its handleAction method. The parameter of this method is an Action interface, and the interface needs to override the action abstract method. I used the report method belonging to test. The output is normal.
Then I want to know, there is a local object of an anonymous class in the method of the test object, and the local object parameter is an anonymous class that implements the interface. Why can report be called in this anonymous class? Does it hold the test.this pointer?
My understanding is that new Speaker().handleAction(new Action(){....
The implementation logic here has nothing to do with test.this, and there is no need to hold test. this???
new Speaker()
不是匿名内部类,它有确切的类名Speakernew Action(){}
是匿名内部类,会在编译的时候给它一个类名(我们假定它的类名叫Test$1,你可以打印this.getClass()看看)看出两者的区别了吗?匿名内部类多出了个{}。
由于
new Action(){}
是在test对象的作用域里被创建的,所以它的外部类是Test。匿名内部类也有构造器,而且和普通类的构造器有点不一样,编译的时候会在匿名内部类的构造器的参数列表之前再插入一个参数,这个参数是外部类的对象的引用,编译之后这个类长这样:
new Action(){...}
实际上是创建了Test$1,并且通过构造器把test对象引用传给Test$1所以匿名内部类持有外部类的引用,且可以调用外部类的方法