oop – In Java gibt es Zweifel daran, dass anonyme innere Klassen externe Klassenmethoden aufrufen
漂亮男人
漂亮男人 2017-05-17 10:07:37
0
1
985

Heute habe ich etwas über innere Klassen gelernt und erfahren, dass innere Klassen dies von äußeren Klassen halten können, sodass OuterClass.this.medthod() in inneren Klassen verwendet werden kann, um auf die entsprechenden Methoden der äußeren Klasse zu verweisen. Aber ich habe den Code geschrieben und er kann ausgeführt werden. Ich verstehe die Aufruflogik jedoch nicht sehr gut.

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();
    }

Das Design ist wie folgt: Das Testobjekt ruft die Methode „Perform“ auf, die ein neues anonymes Klassenobjekt „Speaker“ erstellt. Der Parameter dieser Methode ist eine Aktionsschnittstelle, und die Schnittstelle muss die Aktionszusammenfassung überschreiben Methode. Ich habe die zum Test gehörende Berichtsmethode verwendet. Die Ausgabe ist normal.

Dann möchte ich wissen, dass es in der Methode des Testobjekts ein lokales Objekt einer anonymen Klasse gibt und der lokale Objektparameter eine anonyme Klasse ist, die die Schnittstelle implementiert. Warum kann der Bericht in dieser anonymen Klasse aufgerufen werden? Enthält es den test.this-Zeiger?
Ich verstehe, new Speaker().handleAction(new Action(){....Die Implementierungslogik hier hat nichts mit test.this zu tun, und es besteht keine Notwendigkeit, test.this???

zu halten
漂亮男人
漂亮男人

Antworte allen(1)
洪涛
        public void perform(){
            new Speaker().handleAction(new Action(){
                @Override
                public void action() {
                    report();//???为什么能调用report??
                }
            });
        }

new Speaker()不是匿名内部类,它有确切的类名Speaker
new Action(){}是匿名内部类,会在编译的时候给它一个类名(我们假定它的类名叫Test$1,你可以打印this.getClass()看看)
看出两者的区别了吗?匿名内部类多出了个{}。
由于new Action(){}是在test对象的作用域里被创建的,所以它的外部类是Test。

匿名内部类也有构造器,而且和普通类的构造器有点不一样,编译的时候会在匿名内部类的构造器的参数列表之前再插入一个参数,这个参数是外部类的对象的引用,编译之后这个类长这样:

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(){...}实际上是创建了Test$1,并且通过构造器把test对象引用传给Test$1

        public void perform(){
            new Speaker().handleAction(new Test$1(this));
        }

所以匿名内部类持有外部类的引用,且可以调用外部类的方法

Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage
Über uns Haftungsausschluss Sitemap
Chinesische PHP-Website:Online-PHP-Schulung für das Gemeinwohl,Helfen Sie PHP-Lernenden, sich schnell weiterzuentwickeln!