oop - Di Jawa, keraguan tentang kelas dalaman tanpa nama yang memanggil kaedah kelas luaran
漂亮男人
漂亮男人 2017-05-17 10:07:37
0
1
1045

Hari ini saya belajar tentang kelas dalam dan mengetahui bahawa kelas dalam boleh menyimpan kelas luar ini, supaya OuterClass.this.medthod() boleh digunakan dalam kelas dalam untuk merujuk kaedah kelas luar yang sepadan. Tetapi saya menulis kod itu dan ia boleh dijalankan Walau bagaimanapun, saya tidak memahami logik panggilan dengan baik.

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

Reka bentuk adalah seperti ini Objek ujian memanggil kaedah perform, yang mencipta objek kelas tanpa nama Speaker yang baharu kaedah. Saya menggunakan kaedah laporan kepunyaan ujian. Keluaran adalah normal.

Kemudian saya ingin tahu, terdapat objek tempatan kelas tanpa nama dalam kaedah objek ujian, dan parameter objek tempatan ialah kelas tanpa nama yang melaksanakan antara muka Mengapa laporan boleh dipanggil dalam kelas tanpa nama ini? Adakah ia memegang ujian.penunjuk ini?
Saya faham, new Speaker().handleAction(new Action(){....Logik pelaksanaan di sini tiada kaitan dengan test.this, dan tak perlu adakan test.this???

漂亮男人
漂亮男人

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

Speaker() baharu bukanlah kelas dalaman tanpa nama, ia mempunyai nama kelas yang tepat Speaker
new Action(){} ialah kelas dalaman tanpa nama dan akan diproses semasa penyusunan Beri ia nama kelas (kami menganggap nama kelasnya ialah Test$1, anda boleh mencetak this.getClass() untuk melihat)
Nampak perbezaan antara keduanya? Kelas dalaman awanama mempunyai {} tambahan.
Memandangkan new Action(){} dicipta dalam skop objek ujian, kelas luarannya ialah Test. new Speaker()不是匿名内部类,它有确切的类名Speaker
new Action(){}是匿名内部类,会在编译的时候给它一个类名(我们假定它的类名叫Test,你可以打印this.getClass()看看)
看出两者的区别了吗?匿名内部类多出了个{}。
由于new Action(){}是在test对象的作用域里被创建的,所以它的外部类是Test。

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

Test implements Action {
    final T this
        public void perform(){
            new Speaker().handleAction(new Test(this));
        }
; Test(T thisrrreee){ this.thisrrreee = thisrrreee; } @Override public void action() { thisrrreee.report(); } }

new Action(){...}

Kelas dalaman tanpa nama juga mempunyai pembina, dan ia sedikit berbeza daripada pembina kelas biasa Apabila menyusun, parameter lain akan dimasukkan sebelum senarai parameter pembina kelas dalam tanpa nama Parameter ini adalah rujukan kepada objek daripada kelas luar Apabila menyusun Kelas akan kelihatan seperti ini:

rrreee

new Action(){...} sebenarnya mencipta Test$1 dan menghantar rujukan objek ujian kepada Test$1 melalui constructor🎜 rrreee 🎜Jadi kelas dalaman tanpa nama memegang rujukan kepada kelas luar dan boleh memanggil kaedah kelas luar🎜
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan