System.out.println("lambdaisrun") sebenarnya adalah penubuhan Bagaimana pula dengan kelas dalaman? Sebenarnya, ini adalah ungkapan Lambda yang paling mudah"/> System.out.println("lambdaisrun") sebenarnya adalah penubuhan Bagaimana pula dengan kelas dalaman? Sebenarnya, ini adalah ungkapan Lambda yang paling mudah">
Mula-mula kita melihat tunjuk cara ekspresi Lambda, seperti yang ditunjukkan di bawah:
Kod ini agak mudah, cuma mulakan utas baharu dan cetak ayat, tetapi untuk gambar () -> System.out.println (“ lambda dijalankan “) ini Dianggarkan ramai pelajar keliru tentang kod jenis ini Bagaimana Java mengenal pasti kod jenis ini?
Jika kita menukar tulisan kepada kelas dalaman tanpa nama, ia akan menjadi sangat jelas dan semua orang boleh memahaminya, seperti yang ditunjukkan di bawah:
Adakah itu bermakna ( ) -> System.out.println (“ lambda dijalankan “) Adakah bentuk kod ini sebenarnya mencipta kelas dalam? Sebenarnya, ini adalah ungkapan Lambda yang paling mudah Kami tidak dapat melihat kod sumber dan struktur asasnya melalui IDEA Di sini kami akan memperkenalkan beberapa cara untuk melihat pelaksanaan asasnya.
Kami boleh secara aktif membuang pengecualian semasa pelaksanaan kod dan mencetak timbunan akan menerangkan trajektori berjalan Secara amnya, kaedah ini adalah mudah dan cekap, dan anda pada dasarnya boleh melihat Mari cuba kod tersembunyi dalam banyak kes, seperti yang ditunjukkan di bawah:
Dari timbunan pengecualian, kita dapat melihat bahawa JVM secara automatik mencipta kelas dalaman untuk semasa class ($ muncul beberapa kali dalam timbunan ralat menunjukkan kelas dalaman semasa pelaksanaan kod kelas dalaman, pengecualian dilemparkan, tetapi kod yang ditunjukkan di sini adalah Sumber Tidak Diketahui, jadi kami tidak boleh menyahpepijatnya dalam keadaan biasa , pengecualian Kedua-dua kaedah boleh mendedahkan laluan pelaksanaan kod Kami boleh menetapkan titik putus dan berjalan semula Namun, untuk ungkapan Lambda, melalui kaedah penghakiman pengecualian, kami hanya tahu bahawa terdapat kelas dalaman, tetapi kami tidak dapat melihat kod sumber dalam dalaman. kelas.
javap ialah alat yang disertakan dengan Java untuk melihat fail bytecode kelas Komputer yang telah memasang persekitaran asas Java boleh terus melaksanakan arahan javap, seperti yang ditunjukkan di bawah:
Antara pilihan arahan, kami terutamanya menggunakan perintah -v -verbose untuk mengeluarkan sepenuhnya kandungan fail bytecode.
Seterusnya kami menggunakan arahan javap untuk melihat fail Lambda.class Semasa penerangan, kami akan membawa sedikit pengetahuan tentang fail kelas.
Kami mencari lokasi Lambda.class dalam tetingkap arahan, jalankan arahan: javap -verbose Lambda.class, dan kemudian anda akan melihat senarai panjang perkara, ini dipanggil arahan pemasangan, mari lakukannya seterusnya Biar saya jelaskan (semua bahan rujukan datang daripada Spesifikasi Mesin Maya Java, tiada petikan satu demi satu diperlukan):
Dalam arahan pemasangan, kita boleh mencari senarai panjang jenis dengan mudah bermula dengan Constant pool. Kami memanggilnya sebagai kumpulan malar Ia dipanggil Run-Time Constant Pool dalam bahasa Inggeris. Kami hanya memahaminya sebagai jadual yang diisi dengan pemalar padang, dsb. Setiap elemen dalam jadual dipanggil cpmaklumat cp terdiri daripada pengecam unik (teg) + nama Pada masa ini, terdapat sejumlah jenis teg:
Siarkan beberapa gambar yang kami huraikan: dan #1 dalam lajur pertama mewakili kedudukan yang ditandakan sebagai 1 dalam kumpulan malar; Lajur kedua bagi setiap baris ialah Pengecam unik (teg) cp_info
, sebagai contoh, Methodref sepadan dengan CONSTANT_Methodref dalam jadual di atas (nilai dalam jadual di atas sepadan dengan teg 10), yang bermaksud bahawa baris semasa mewakili maklumat perihalan kaedah, seperti nama kaedah, Makna khusus jenis parameter input, jenis parameter output, dll. boleh didapati dalam Spesifikasi Mesin Maya Java Tangkapan skrin Methodref adalah seperti berikut:
cp_info
Nombor setiap baris Tiga lajur Jika ia adalah nilai tertentu, nilai khusus akan dipaparkan secara langsung Jika ia adalah nilai kompleks, rujukan akan dipaparkan Contohnya, bertanda merah 2 dalam gambar merujuk kepada dua
cp_info
Untuk jenis cp_info yang lebih penting, kami menerangkan maksudnya: cp_info
InvokeDynamic mewakili kaedah panggilan dinamik, yang akan kami terangkan secara terperinci kemudian; jenis medan;
NameAndType ialah penerangan bagi medan dan jenis kaedah; kaedah, kami tidak tahu yang khusus pada masa penyusunan Kaedah itu, tetapi anda pasti akan tahu kaedah mana yang dipanggil semasa menjalankan
MethodType jenis kaedah dinamik, anda hanya akan tahu apa; jenis kaedahnya ialah apabila berjalan secara dinamik.
Daripada 3 tempat yang ditandakan dengan warna merah dalam gambar di atas, kami menemui kod Ljava/lang/invoke/MethodHandles$Lookup, java/lang/invoke/LambdaMetafactory.metafactory yang serupa dengan ini, MethodHandles dan LambdaMetafactory ialah kaedah penting di bawah pakej java.lang.invoke terutamanya melaksanakan fungsi bahasa dinamik , dsb. telah ditentukan , dan invoke melaksanakan bahasa dinamik, yang bermaksud bahawa jenis kelas, kaedah dan medan tidak diketahui semasa menyusun, dan hanya diketahui semasa dijalankan.
Pertama, mari kita lihat arahan pemasangan kaedah mudah:
2: Dalam operasi sebenar Apabila JVM menemui arahan invokedynamic bagi kaedah mudah, ia akan secara dinamik memanggil kaedah LambdaMetafactory.metafactory dan melaksanakan kaedah Runnable.run tertentu.
Jadi pelaksanaan khusus nilai ekspresi Lambda boleh dikaitkan dengan arahan JVM invokedynamic Ia adalah tepat kerana arahan ini walaupun anda tidak tahu apa yang perlu dilakukan semasa menyusun, anda boleh menemui pelaksanaan khusus. apabila berjalan secara dinamik.
Kemudian mari kita lihat pada penghujung output arahan pemasangan Kami mendapati kelas dalaman ditemui dalam kaedah penghakiman pengecualian, seperti yang ditunjukkan di bawah:
Dalam gambar di atas Terdapat banyak anak panah, dan semua maklumat kelas dalaman semasa dinyatakan dengan jelas lapisan demi lapisan.
Atas ialah kandungan terperinci Bagaimana untuk membaca kod sumber Lambda dalam Java. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!