Bagaimana untuk membaca kod sumber Lambda dalam Java
1. Demo
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.
2. Kaedah penghakiman pengecualian
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.
3. Kaedah arahan javap
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:
- Perkataan Kolam Malar dalam gambar bermaksud maklumat semasa ialah kolam malar;
- Setiap baris ialah
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: -
pada kedudukan 13 dan 14. , 13 bermakna nama kaedah ialah init, 14 bermakna kaedah itu tidak mempunyai nilai pulangan, dan gabungannya daripada nama kaedah dan jenis pulangan ialah pembina tanpa parameter;cp_info
Nombor setiap baris Tiga lajur Jika ia adalah nilai tertentu, nilai khusus akan dipaparkan secara langsung Jika ia adalah nilai kompleks, rujukanakan 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.
Contohnya, baris kod ini: Runnable runnable = () -> System.out.println(“lambda is run”); does , hanya apabila berjalan anda akan tahu bahawa ini mewakili kaedah Runnable.run(). Banyak kelas dalam pakej invoke direka untuk mewakili ini (), yang kami panggil kaedah mengendalikan (MethodHandler, pengkompil hanya tahu bahawa ini adalah kaedah pengendalian, dan tidak tahu kaedah yang sebenarnya saya lakukan). tidak tahu sehingga masanya, jadi persoalannya ialah, apabila JVM melaksanakan, bagaimanakah ia tahu bahawa pengendalian kaedah () sebenarnya melaksanakan kaedah Runnable.run()? Pertama, mari kita lihat arahan pemasangan kaedah mudah:
pemanggil parameter input kaedah metafaktor mewakili lokasi sebenar panggilan dinamik, invokedName mewakili nama kaedah panggilan, dan invokedType mewakili berbilang input bagi Parameter panggilan dan parameter output, samMethodType mewakili parameter pelaksana khusus, implMethod mewakili pelaksana sebenar dan instantiatedMethodType adalah bersamaan dengan implMethod. Ringkasan perkara di atas: 1: Daripada kaedah mudah arahan pemasangan, kita dapat melihat bahawa kaedah Runnable.run akan dilaksanakan2: 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!

Alat AI Hot

Undresser.AI Undress
Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover
Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool
Gambar buka pakaian secara percuma

Clothoff.io
Penyingkiran pakaian AI

AI Hentai Generator
Menjana ai hentai secara percuma.

Artikel Panas

Alat panas

Notepad++7.3.1
Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina
Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1
Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6
Alat pembangunan web visual

SublimeText3 versi Mac
Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Topik panas



Panduan untuk Square Root di Java. Di sini kita membincangkan cara Square Root berfungsi di Java dengan contoh dan pelaksanaan kodnya masing-masing.

Panduan Nombor Sempurna di Jawa. Di sini kita membincangkan Definisi, Bagaimana untuk menyemak nombor Perfect dalam Java?, contoh dengan pelaksanaan kod.

Panduan untuk Penjana Nombor Rawak di Jawa. Di sini kita membincangkan Fungsi dalam Java dengan contoh dan dua Penjana berbeza dengan contoh lain.

Panduan untuk Weka di Jawa. Di sini kita membincangkan Pengenalan, cara menggunakan weka java, jenis platform, dan kelebihan dengan contoh.

Panduan untuk Nombor Smith di Jawa. Di sini kita membincangkan Definisi, Bagaimana untuk menyemak nombor smith di Jawa? contoh dengan pelaksanaan kod.

Dalam artikel ini, kami telah menyimpan Soalan Temuduga Spring Java yang paling banyak ditanya dengan jawapan terperinci mereka. Supaya anda boleh memecahkan temuduga.

Java 8 memperkenalkan API Stream, menyediakan cara yang kuat dan ekspresif untuk memproses koleksi data. Walau bagaimanapun, soalan biasa apabila menggunakan aliran adalah: bagaimana untuk memecahkan atau kembali dari operasi foreach? Gelung tradisional membolehkan gangguan awal atau pulangan, tetapi kaedah Foreach Stream tidak menyokong secara langsung kaedah ini. Artikel ini akan menerangkan sebab -sebab dan meneroka kaedah alternatif untuk melaksanakan penamatan pramatang dalam sistem pemprosesan aliran. Bacaan Lanjut: Penambahbaikan API Java Stream Memahami aliran aliran Kaedah Foreach adalah operasi terminal yang melakukan satu operasi pada setiap elemen dalam aliran. Niat reka bentuknya adalah

Panduan untuk TimeStamp to Date di Java. Di sini kita juga membincangkan pengenalan dan cara menukar cap waktu kepada tarikh dalam java bersama-sama dengan contoh.
