oop - Java中,關(guān)于匿名內(nèi)部類調(diào)用外部類方法的疑惑
問題描述
今天學(xué)習(xí)了內(nèi)部類的知識(shí),知道內(nèi)部類是可以持有外部類的this,從而在內(nèi)部類中可以使用OuterClass.this.medthod()來引用相應(yīng)外部類方法。但是我寫出下代碼,可以運(yùn)行,然而其中的調(diào)用邏輯我不是很明白,望賜教!
public class test {public void report(){ System.out.println('I’m invoked!');}public void perform(){ new Speaker().handleAction(new Action(){@Overridepublic void action() { report();//???為什么能調(diào)用report??} });}public static void main(String[] args) { new test().perform();//測(cè)試代碼} } class Speaker{void handleAction(Action act){ act.action();} } interface Action{void action(); }
其中設(shè)計(jì)是這樣的,test對(duì)象調(diào)用perform方法,該方法其中新建一個(gè)Speaker匿名類對(duì)象,該對(duì)象調(diào)用了其handleAction方法,該方法的參數(shù)是一個(gè)Action接口,接口需要重寫action抽象方法。我使用了屬于test的report方法。輸出是正常的。
那么我想知道,test對(duì)象的方法中有一個(gè)匿名類的局部對(duì)象,局部對(duì)象參數(shù)是一個(gè)實(shí)現(xiàn)接口的匿名類,為什么在這個(gè)匿名類中可以調(diào)用report?它持有test.this指針嗎?我理解中,new Speaker().handleAction(new Action(){....這里面的實(shí)現(xiàn)邏輯和test.this一點(diǎn)關(guān)系都沒有,也沒有必要持有test.this???
問題解答
回答1:public void perform(){ new Speaker().handleAction(new Action(){@Overridepublic void action() { report();//???為什么能調(diào)用report??} });}
new Speaker()不是匿名內(nèi)部類,它有確切的類名Speakernew Action(){}是匿名內(nèi)部類,會(huì)在編譯的時(shí)候給它一個(gè)類名(我們假定它的類名叫Test$1,你可以打印this.getClass()看看)看出兩者的區(qū)別了嗎?匿名內(nèi)部類多出了個(gè){}。由于new Action(){}是在test對(duì)象的作用域里被創(chuàng)建的,所以它的外部類是Test。
匿名內(nèi)部類也有構(gòu)造器,而且和普通類的構(gòu)造器有點(diǎn)不一樣,編譯的時(shí)候會(huì)在匿名內(nèi)部類的構(gòu)造器的參數(shù)列表之前再插入一個(gè)參數(shù),這個(gè)參數(shù)是外部類的對(duì)象的引用,編譯之后這個(gè)類長這樣:
Test$1 implements Action { final T this$0; Test$1(T this$0){this.this$0 = this$0; }@Override public void action() {this$0.report(); }}
new Action(){...}實(shí)際上是創(chuàng)建了Test$1,并且通過構(gòu)造器把test對(duì)象引用傳給Test$1
public void perform(){ new Speaker().handleAction(new Test$1(this));}
所以匿名內(nèi)部類持有外部類的引用,且可以調(diào)用外部類的方法
