Teman-teman yang mempelajari Java pasti tahu bahwa Java telah menggunakan panji independensi platform sejak awal, dengan mengatakan "tulis sekali, jalankan di mana saja". Faktanya, jika menyangkut hal yang tidak relevan, platform Java memiliki hal lain yang tidak relevan, yaitu kemandirian bahasa . , untuk mencapai kemandirian bahasa, maka struktur file kelas dalam sistem Java atau Sangat penting untuk mengatakan bahwa ini adalah bytecode. Faktanya, Java telah memiliki dua set spesifikasi sejak awal, satu adalah spesifikasi bahasa Java, dan yang lainnya adalah spesifikasi mesin virtual Java. Spesifikasi bahasa Java hanya menetapkan batasannya terkait dengan bahasa dan Aturan Java, dan spesifikasi mesin virtual benar-benar dirancang dari perspektif lintas platform. Hari ini kita akan mengambil contoh praktis untuk melihat seperti apa tampilan bytecode yang terkait dengan file Kelas di Java. Artikel ini pertama-tama akan menjelaskan secara umum apa isi Kelas, dan kemudian menggunakan kelas Java yang sebenarnya untuk menganalisis struktur file kelas.
Sebelum melanjutkan, ada baiknya kita perjelas terlebih dahulu beberapa hal berikut ini:
1) File kelas terdiri dari aliran byte berbasis 8 byte. Aliran byte ini disusun secara ketat dalam urutan yang ditentukan, dan tidak ada celah antar byte. Untuk file yang melebihi 8 byte, Data akan disimpan dalam urutan Big-Endian, artinya, byte tingkat tinggi disimpan di alamat rendah, dan byte tingkat rendah disimpan di alamat tinggi. Ini juga merupakan kunci untuk file kelas lintas platform, karena arsitektur PowerPC menggunakan urutan penyimpanan Big-Endian, sedangkan prosesor seri x86 menggunakan urutan penyimpanan Little-Endian, sehingga agar file Kelas dipertahankan di bawah setiap arsitektur prosesor Penyimpanan terpadu Agar, spesifikasi mesin virtual harus disatukan.
2) Struktur file Kelas menggunakan struktur mirip bahasa C untuk menyimpan data. Ada dua tipe utama item data, nomor tak bertanda dan tabel. Nomor tak bertanda digunakan untuk menyatakan angka, referensi indeks, dan string, seperti u1, u2 , u4 dan u8 masing-masing mewakili 1 byte, 2 byte, 4 byte, dan 8 byte nomor yang tidak ditandatangani, dan tabelnya adalah struktur gabungan yang terdiri dari beberapa nomor yang tidak ditandatangani dan tabel lainnya. Mungkin semua yang ada di sini belum begitu paham tentang apa itu angka dan tabel unsigned, namun tidak masalah saya akan menjelaskannya dengan contoh ketika saya memberikan contoh di bawah ini.
Setelah memperjelas dua poin di atas, mari kita lihat data spesifik yang terkandung dalam aliran byte yang disusun dalam urutan ketat di file Kelas:
Pada gambar di atas ada satu hal yang perlu kita perhatikan, misalnya cp_info, cp_info merepresentasikan konstanta pool. Pada gambar di atas, Constant_pool[constant_pool_count-1] digunakan untuk merepresentasikan konstanta pool dengan Constant_pool_co. unt-1 konstan, di sini dinyatakan dalam bentuk array, tapi jangan salah mengira bahwa panjang konstan semua kumpulan konstan adalah sama. Faktanya, tempat ini menggunakan metode array hanya untuk kemudahan deskripsi, tapi tidak seperti ini. Dalam bahasa pemrograman, array bertipe int memiliki panjang setiap int yang sama. Setelah memperjelas poin ini, mari kita melihat kembali dan melihat apa yang secara spesifik diwakili oleh setiap item pada gambar di atas.
1) sihir u4 mewakili angka ajaib, dan angka ajaib menempati 4 byte. Artinya, jenis filenya adalah file Kelas, bukan gambar JPG atau film AVI. Angka ajaib yang sesuai dengan file Kelas adalah 0xCAFEBABE.
2) u2 minor_version mewakili nomor versi minor dari file Kelas, dan nomor versi ini adalah representasi nomor tak bertanda tangan dari tipe u2.
3) u2 mayor_version mewakili nomor versi utama file Kelas, dan nomor versi utama adalah representasi nomor tak bertanda tangan dari tipe u2. mayor_version dan minor_version terutama digunakan untuk menunjukkan apakah mesin virtual saat ini menerima versi file Kelas saat ini. Versi file Kelas yang dikompilasi oleh versi kompiler Java yang berbeda juga berbeda. Versi mesin virtual yang lebih tinggi mendukung struktur file Kelas yang dikompilasi oleh kompiler versi lebih rendah. Misalnya, mesin virtual yang terkait dengan Java SE 6.0 mendukung struktur file Kelas yang dikompilasi oleh kompiler Java SE 5.0, namun tidak sebaliknya.
4) u2 Constant_pool_count mewakili jumlah kumpulan konstan. Di sini kita perlu fokus pada apa itu kumpulan konstanta. Harap jangan bingung dengan kumpulan konstanta runtime dalam model memori Jvm. Kumpulan konstanta dalam file Kelas terutama menyimpan referensi literal dan simbol, di mana literal terutama menyertakan string nilai konstanta akhir atau Atau nilai awal dari atribut tertentu, dll., sedangkan referensi simbol terutama menyimpan nama kelas dan antarmuka yang sepenuhnya memenuhi syarat, nama bidang dan deskriptor, nama metode dan deskriptor. Nama-nama di sini mungkin mudah dipahami oleh semua orang, seperti untuk konsep deskriptor, kita akan membicarakannya nanti ketika kita membahas tabel bidang dan tabel metode. Selain itu, semua orang tahu bahwa model memori Jvm terdiri dari heap, stack, area metode, dan penghitung program, dan ada area di area metode yang disebut kumpulan konstanta runtime. Hal-hal yang disimpan dalam kumpulan konstanta runtime sebenarnya adalah keabadian kompiler. Berbagai referensi literal dan simbol, tetapi kumpulan konstanta runtime bersifat dinamis. Ia dapat menambahkan konstanta lain ke dalamnya saat runtime.
5) cp_info mewakili kumpulan konstan, yang berisi berbagai referensi literal dan simbol yang disebutkan di atas. Ada total 14 item data yang ditempatkan di kumpulan konstanta di Spesifikasi Mesin Virtual Java Java SE 7 Edition. Setiap konstanta adalah tabel, dan setiap konstanta menggunakan tag parsial umum untuk menunjukkan jenis konstanta tersebut.
Detail spesifiknya dijelaskan secara singkat di bawah ini dan kami akan menyempurnakannya dalam contoh selanjutnya.
Bendera tag CONSTANT_Utf8_info adalah 1, bendera tag string berkode UTF-8 CONSTANT_Integer_info adalah 3, bendera tag CONSTANT_Float_info literal bilangan bulat adalah 4, bendera tag CONSTANT_Long_info literal floating point adalah 5, bendera tag CONSTANT_Double_info literal bilangan bulat panjang Bitnya adalah 6, tanda tag CONSTANT_Class_info literal presisi ganda adalah 7, Tag CONSTANT_String_info referensi simbolis dari kelas atau antarmuka adalah 8, tag CONSTANT_Fieldref_info literal dari tipe string adalah 9, referensi simbolis dari tag CONSTANT_Methodref_info bidang adalah 10, referensi simbolis dari metode di kelas tag CONSTANT_InterfaceMethodref_info adalah 11, Simbolis referensi ke metode dalam tag antarmuka CONSTANT_NameAndType_info Tandai bit 12, nama field dan metode, dan referensi simbolik ke tipe
6) u2 access_flags mewakili informasi akses kelas atau antarmuka, seperti yang ditunjukkan pada gambar berikut:
7) u2 this_class mewakili indeks kumpulan konstan kelas, menunjuk ke konstanta CONSTANT_Class_info di kumpulan konstan
8) u2 super_class mewakili indeks kelas super, menunjuk ke konstanta CONSTANT_Class_info di kumpulan konstan
9) u2 interface_counts mewakili jumlah antarmuka
10) u2 interface[interface_counts] mewakili tabel antarmuka, setiap item di dalamnya menunjuk ke konstanta CONSTANT_Class_info di kumpulan konstan
11) u2 field_count mewakili jumlah variabel instan dan variabel kelas dari kelas tersebut
12) field_info field[fields_count] mewakili informasi tabel field, dimana struktur tabel field seperti dibawah ini:
Pada gambar di atas, access_flags mewakili representasi akses dari bidang tersebut. Misalnya, bidang tersebut bersifat publik, pribadi, dan dilindungi. dll., name_index mewakili nama bidang, menunjuk ke konstanta bertipe CONSTANT_UTF8_info di kumpulan konstan, descriptor_index mewakili deskriptor bidang, yang juga menunjuk ke konstanta bertipe CONSTANT_UTF8_info di kumpulan konstan, atribut_count mewakili jumlah tabel atribut di tabel bidang, dan tabel atribut Ini adalah struktur yang dapat diperluas yang digunakan untuk mendeskripsikan bidang, metode, dan atribut kelas. Versi berbeda dari mesin virtual Java mendukung jumlah tabel atribut yang berbeda.
13) u2 method_count mewakili jumlah tabel metode
14) method_info mewakili tabel metode. Struktur spesifik tabel metode adalah seperti yang ditunjukkan pada gambar di bawah ini:
Diantaranya, access_flags mewakili representasi akses metode, name_index mewakili indeks nama, descriptor_index mewakili deskriptor metode, atribut_count dan atribut_info mirip dengan tabel atribut di tabel bidang, kecuali atribut di tabel atribut pada tabel field dan tabel metode berbeda, misalnya Atribut Code pada tabel metode mewakili kode metode, tetapi tidak ada atribut Code pada tabel field. Berapa banyak atribut yang ada pada Kelas tertentu akan dibahas nanti ketika kita melihat tabel atribut pada struktur file Kelas.
15) atribut_count mewakili jumlah tabel atribut. Ketika berbicara tentang tabel atribut, kita perlu memperjelas poin-poin berikut:
Tabel atribut ada di akhir struktur file Kelas, di tabel bidang, tabel metode, dan atribut Kode. Artinya, tabel atribut juga bisa ada di tabel atribut. Panjang tabel atribut tidak tetap. Atribut yang berbeda memiliki panjang yang berbeda
Setelah menjelaskan komposisi setiap item dalam struktur file Kelas di atas, kami menggunakan contoh praktis untuk menjelaskan konten berikut.
Copy kode kodenya sebagai berikut:
paket com.ejushang.TestClass;
kelas publik TestClass mengimplementasikan Super{
private static final int staticVar = 0;
pribadi int instanceVar=0;
metode instance int publik(int param){
kembalikan param+1;
}
}
antarmuka Super{ }
Struktur biner TestClass.class yang sesuai dengan TestClass.java yang dikompilasi melalui javac jdk1.6.0_37 ditunjukkan pada gambar di bawah ini:
Selanjutnya, kita akan mengurai aliran byte pada gambar di atas berdasarkan struktur file Kelas yang disebutkan sebelumnya.
1) Angka ajaib Dari struktur file Class kita mengetahui bahwa 4 byte pertama adalah angka ajaib. Pada gambar di atas, isi dari alamat 00000000h-00000003h adalah angka ajaib. kita dapat mengetahui angka ajaib dari file Kelas. Angka tersebut adalah 0xCAFEBABE.
2) Nomor versi mayor dan minor <br/>4 byte berikutnya adalah nomor versi mayor dan minor. Dari gambar di atas, kita dapat melihat bahwa nomor yang bersesuaian dari 00000004h-00000005h adalah 0×0000, jadi versi_minor dari Kelas. adalah 0×0000, dan konten yang sesuai dari 00000006h-00000007h adalah 0×0032, jadi versi mayor_version dari file Kelas adalah 0×0032, yang merupakan versi mayor dan minor yang sesuai dengan Kelas yang dikompilasi oleh jdk1.6.0 tanpa parameter sasaran.
3) Jumlah pool konstan <br/>2 byte berikutnya mewakili jumlah pool konstan dari 00000008h-00000009h Dari gambar di atas kita dapat mengetahui bahwa nilainya adalah 0×0018, yaitu 24 dalam desimal, tetapi untuk desimalnya adalah 24. Jumlah kumpulan konstan perlu diperjelas. Jumlah kumpulan konstan adalah konstanta_kumpulan_hitungan-1. Alasan mengapa dikurangi satu adalah karena indeks 0 berarti item data di kelas tidak mereferensikan konstanta apa pun di kumpulan konstan.
4) Kumpulan Konstan <br/>Kita telah mengatakan di atas bahwa ada berbagai jenis konstanta dalam kumpulan konstan. Mari kita lihat konstanta pertama dari TestClass.class. Kita tahu bahwa setiap konstanta diwakili oleh pengenal tag tipe u1. Jenis konstanta pada 0000000ah pada gambar di atas Isinya 0x0A yang diubah ke sistem sekunder adalah 10. Dari uraian tipe konstanta di atas terlihat bahwa konstanta dengan tag 10 adalah Constant_Methodref_info, dan struktur Constant_Methodref_info seperti terlihat pada gambar di bawah ini:
Diantaranya, class_index menunjuk ke konstanta bertipe CONSTANT_Class_info pada kumpulan konstanta. Terlihat dari struktur file biner TestClass bahwa nilai class_index adalah 0×0004 (alamatnya 0000000bh-0000000ch), artinya menunjuk ke konstanta keempat.
name_and_type_index menunjuk ke konstanta bertipe CONSTANT_NameAndType_info di kumpulan konstan. Seperti terlihat pada gambar di atas, nilai name_and_type_index adalah 0×0013 yang artinya menunjuk ke konstanta ke-19 pada kumpulan konstanta.
Selanjutnya, Anda dapat menggunakan metode yang sama untuk mencari semua konstanta di kumpulan konstanta. Namun, JDK menyediakan alat praktis yang memungkinkan kita melihat konstanta yang terdapat dalam kumpulan konstanta. Anda bisa mendapatkan semua konstanta di kumpulan konstan melalui javap -verbose TestClass. Tangkapan layarnya adalah sebagai berikut:
Dari gambar di atas terlihat jelas bahwa terdapat 24 konstanta pada kumpulan konstanta di TestClass. Jangan lupakan konstanta ke-0, karena konstanta ke-0 digunakan untuk menunjukkan bahwa item data di Kelas tidak mereferensikan konstanta apa pun di dalam kelas. kolam konstan. Dari analisa di atas kita mengetahui bahwa metode representasi konstanta pertama dari TestClass adalah konstanta keempat yang ditunjuk oleh class_index adalah java/lang/Object, dan nilai konstanta ke-19 yang ditunjukkan oleh name_and_type_index adalah <init>:()V terlihat di sini bahwa konstanta pertama yang mewakili suatu metode mewakili metode konstruktor instance yang dihasilkan oleh kompiler Java. Konstanta lain dalam kumpulan konstanta dapat dianalisis dengan cara yang sama. Oke, setelah menganalisis kumpulan konstan, mari kita analisis access_flags selanjutnya.
5) u2 access_flags mewakili informasi akses tentang kelas atau antarmuka. Misalnya, Kelas mewakili apakah itu kelas atau antarmuka, apakah itu publik, statis, final, dll. Arti dari tanda akses spesifik telah disebutkan sebelumnya. Mari kita lihat tanda akses TestClass. Bendera akses Kelas adalah dari 0000010dh-0000010e, dan nilainya adalah 0×0021. Berdasarkan bit bendera dari berbagai bendera akses yang disebutkan sebelumnya, kita dapat mengetahui: 0×0021=0×0001|0×0020, yaitu, ACC_PUBLIC dan ACC_SUPER Benar, ACC_PUBLIC mudah dimengerti, dan ACC_SUPER adalah flag yang akan dibawa oleh kelas yang dikompilasi setelah jdk1.2.
6) u2 this_class mewakili nilai indeks kelas, yang digunakan untuk mewakili nama kelas yang sepenuhnya memenuhi syarat. Nilai indeks kelas seperti yang ditunjukkan pada gambar di bawah ini:
Terlihat jelas dari gambar di atas, nilai indeks kelas adalah 0×0003, yang sesuai dengan konstanta ketiga dari kumpulan konstanta. Melalui hasil javap, kita mengetahui bahwa konstanta ketiga adalah konstanta bertipe CONSTANT_Class_info, melalui yang dapat kita ketahui detail lengkap kelasnya. Nama yang memenuhi syarat adalah: com/ejushang/TestClass /TestClass
7) u2 super_class mewakili nilai indeks kelas induk dari kelas saat ini. Nilai indeks menunjuk ke konstanta bertipe CONSTANT_Class_info di kumpulan konstan 0×0004. Periksa Empat konstanta pertama kumpulan konstanta, dapat dilihat bahwa nama kelas induk TestClass yang sepenuhnya memenuhi syarat adalah: java/lang/Object
8) interfaces_count dan interfaces[interfaces_count] mewakili jumlah antarmuka dan setiap antarmuka tertentu. Jumlah antarmuka dan antarmuka TestClass seperti yang ditunjukkan pada gambar di bawah ini, di mana 0×0001 berarti jumlah antarmuka adalah 1, dan 0× 0005 berarti indeks antarmuka dalam nilai kumpulan konstan, temukan konstanta kelima dalam kumpulan konstan, tipenya CONSTANT_Class_info, dan nilainya: com/ejushang/TestClass/Super
9) field_count dan field_info , field_count mewakili jumlah tabel field_info di kelas, dan field_info mewakili variabel instan dan variabel kelas dari kelas tersebut. Perlu dicatat di sini bahwa field_info tidak menyertakan bidang yang diwarisi dari kelas induk field_info seperti terlihat pada gambar di bawah ini:
Diantaranya, access_flags mewakili access flag dari field tersebut, seperti public, private, protected, static, final, dll. Nilai access_flags seperti terlihat pada gambar di bawah ini:
Diantaranya, name_index dan descriptor_index keduanya merupakan nilai indeks dari kumpulan konstan, yang masing-masing mewakili nama bidang dan deskriptor bidang. Nama bidang mudah dimengerti, tetapi bagaimana memahami deskriptornya bidang? Faktanya, dalam spesifikasi JVM, deskriptor bidang ditentukan seperti yang ditunjukkan pada gambar berikut:
Diantaranya, setiap orang perlu memperhatikan baris terakhir gambar di atas, yang mewakili deskriptor array satu dimensi. Deskriptor untuk String[][] adalah [[ Ljava/lang/String, dan deskripsinya int[][] Simbolnya adalah [[I. Atribut_count dan atribut_info berikut masing-masing mewakili jumlah tabel atribut dan tabel atribut. Mari kita ambil TestClass di atas sebagai contoh dan lihat tabel bidang TestClass.
Pertama, mari kita lihat jumlah field. Jumlah field di TestClass seperti yang ditunjukkan pada gambar di bawah ini:
Seperti terlihat pada gambar di atas, TestClass memiliki dua field. Melihat kode sumber TestClass, kita dapat melihat bahwa memang hanya ada dua field. Selanjutnya, mari kita lihat field pertama private int staticVar, yang Representasi biner dalam file Kelas seperti yang ditunjukkan di bawah ini:
Diantaranya, 0x001A mewakili tanda akses. Dengan melihat tabel access_flags, kita dapat mengetahui bahwa itu adalah ACC_PRIVATE, ACC_STATIC, ACC_FINAL. Selanjutnya, 0×0006 dan 0×0007 masing-masing mewakili konstanta ke-6 dan ke-7 dalam kumpulan konstan melihat kumpulan konstanta, kita dapat mengetahui bahwa nilainya adalah: staticVar dan I, di mana staticVar adalah nama bidang dan I adalah deskriptor bidang. Melalui penjelasan deskriptor di atas, yang saya uraikan adalah variabel bertipe int, selanjutnya 0×0001 merepresentasikan banyaknya tabel atribut pada tabel field staticVar ke bidang staticVar. 0×0008 mewakili konstanta ke-8 dalam kumpulan konstanta. Melihat kumpulan konstanta, Anda dapat melihat bahwa atribut ini adalah atribut ConstantValue, dan format atribut ConstantValue adalah seperti yang ditunjukkan pada gambar di bawah ini:
Diantaranya, atribut_nama_index menyatakan indeks kumpulan konstan dari nama atribut. Dalam contoh ini, itu adalah ConstantValue. Atribut_length dari ConstantValue memiliki panjang tetap 2, dan ConstantValue_index mewakili referensi dalam kumpulan konstan ×0009. Anda dapat melihat konstanta ke-9. Anda tahu, ini mewakili konstanta bertipe CONSTANT_Integer_info yang nilainya 0.
Karena itu private static final int staticVar=0, mari kita bicara tentang private int instanceVar=0 dari TestClass, representasi biner dari instanceVar adalah seperti yang ditunjukkan pada gambar di bawah ini:
Diantaranya, 0×0002 berarti tanda aksesnya adalah ACC_PRIVATE, 0x000A berarti nama field, yang menunjuk ke konstanta ke-10 di pool konstan. Melihat pool konstan, Anda dapat mengetahui bahwa nama field adalah instanceVar, dan 0× 0007 mewakili deskriptor bidang, yang menunjuk ke konstanta ke-7 dalam kumpulan konstanta. Melihat kumpulan konstanta, Anda dapat mengetahui bahwa konstanta ke-7 adalah I, yang mewakili tipe instanceVar. Terakhir, 0×0000 mewakili bahwa jumlah tabel atribut adalah 0. .
10) metode_hitungan dan metode_info , dimana metode_hitung mewakili jumlah metode, dan metode_info mewakili tabel metode, dimana struktur tabel metode seperti terlihat pada gambar di bawah ini:
Seperti dapat dilihat dari gambar di atas, struktur method_info dan field_info sangat mirip. Semua bit flag dan nilai access_flag pada tabel metode seperti yang ditunjukkan pada gambar di bawah ini:
Diantaranya, name_index dan descriptor_index mewakili nama dan deskriptor metode, dan keduanya merupakan indeks yang masing-masing menunjuk ke kumpulan konstan. Di sini kita perlu menjelaskan deskriptor metode. Struktur deskriptor metode adalah: (daftar parameter) nilai kembalian. Misalnya, deskriptor public int instanceMethod(int param) adalah: (I) I, yang artinya memiliki int. tipe parameter. Dan nilai yang dikembalikan juga merupakan metode bertipe int. Berikutnya adalah jumlah atribut dan tabel atribut. Meskipun tabel metode dan tabel bidang keduanya memiliki jumlah atribut dan tabel atribut, atribut yang dikandungnya adalah berbeda. Selanjutnya, mari kita lihat representasi biner dari tabel metode menggunakan TestClass. Pertama, mari kita lihat jumlah tabel metode. Tangkapan layarnya adalah sebagai berikut:
Terlihat dari gambar di atas, jumlah tabel metode adalah 0×0002 yang artinya ada dua metode.Selanjutnya mari kita analisa metode pertama.Mari kita lihat dulu access_flag, name_index, descriptor_index dari metode pertama TestClass. Tangkapan layarnya seperti berikut:
Dari gambar di atas, kita dapat mengetahui bahwa access_flags adalah 0×0001. Dari uraian flag access_flags di atas, kita dapat melihat bahwa nilai access_flags dari metode tersebut adalah ACC_PUBLIC, dan name_index adalah 0x000B. Konstanta ke-11, mengetahui bahwa nama metodenya adalah <init>, 0x000C berarti descriptor_index berarti konstanta ke-12 dalam kumpulan konstanta, dan nilainya adalah ()V, yang berarti metode <init> tidak memiliki parameter dan nilai kembalian. Faktanya, ini adalah kompiler metode konstruktor instance yang dibuat secara otomatis. 0×0001 berikutnya menunjukkan bahwa tabel metode dari metode <init> memiliki 1 atribut. Tangkapan layar atributnya adalah sebagai berikut:
Seperti dapat dilihat dari gambar di atas, konstanta dalam kumpulan konstanta yang sesuai dengan 0x000D adalah Kode, yang mewakili atribut Kode dari metode tersebut. Jadi di sini semua orang harus memahami bahwa kode metode disimpan dalam atribut Kode di dalam atribut tabel di tabel metode file Kelas. Selanjutnya kita analisa atribut Code. Struktur atribut Code ditunjukkan pada gambar di bawah ini:
Diantaranya, atribut_nama_index menunjuk ke konstanta yang nilainya adalah Kode di kumpulan konstan, dan panjang atribut_length menunjukkan panjang tabel atribut Kode (perlu dicatat bahwa panjangnya tidak termasuk panjang 6 byte dari atribut_nama_index dan atribut_length ).
max_stack mewakili kedalaman tumpukan maksimum. Mesin virtual mengalokasikan kedalaman operan dalam bingkai tumpukan berdasarkan nilai ini saat runtime, dan max_locals mewakili ruang penyimpanan tabel variabel lokal.
Unit max_locals adalah slot, yang merupakan unit terkecil bagi mesin virtual untuk mengalokasikan memori untuk variabel lokal. Saat runtime, tipe data yang tidak melebihi tipe 32-bit, seperti byte, char, int, dll., menempati 1. slot, sedangkan ganda dan Panjang Tipe data 64-bit perlu mengalokasikan 2 slot. Selain itu, nilai max_locals bukanlah jumlah memori yang dibutuhkan oleh semua variabel lokal, karena slot dapat digunakan kembali ketika variabel lokal melebihi cakupannya, variabel lokal slot yang terisi akan digunakan kembali.
code_length mewakili jumlah instruksi bytecode, dan code mewakili instruksi bytecode. Dari gambar di atas, kita dapat mengetahui bahwa tipe kodenya adalah u1. Nilai tipe u1 adalah 0×00-0xFF, dan desimal yang sesuai adalah 0- 255. Saat ini, spesifikasi mesin virtual telah menetapkan lebih dari 200 instruksi.
pengecualian_tabel_panjang dan tabel_pengecualian masing-masing mewakili informasi pengecualian yang sesuai dengan metode tersebut.
atribut_count dan atribut_info mewakili jumlah atribut dan tabel atribut masing-masing dalam atribut Kode. Dari sini dapat dilihat bahwa tabel atribut sangat fleksibel dalam struktur file Kelas. Dapat ada di file Kelas, tabel metode, bidang tabel dan atribut Kode.
Selanjutnya kita lanjutkan menganalisa contoh di atas. Dari screenshot atribut Code metode init di atas, kita dapat melihat bahwa panjang tabel atribut adalah 0×00000026, nilai max_stack adalah 0×0002, dan nilainya dari max_locals adalah 0× 0001, panjang code_length adalah 0x0000000A, lalu 00000149h- 00000152h adalah bytecode. Selanjutnya, panjang pengecualian_tabel_panjang adalah 0×0000, dan nilai atribut_count adalah 0×0001. Nilai 00000157h-00000158h adalah 0x000E, yang mewakili nama atribut dalam kumpulan konstan untuk mendapatkan yang ke-14. Nilai konstanta adalah LineNumberTable, LineNu mberTable digunakan untuk mendeskripsikan korespondensi antara nomor baris kode sumber Java dan nomor baris bytecode. Ini bukan atribut yang diperlukan saat runtime. Jika Anda membatalkan pembuatan informasi ini melalui parameter kompiler -g:none, dampak terbesar akan terjadi menjadi Ketika pengecualian terjadi, nomor baris kesalahan tidak dapat ditampilkan di tumpukan, dan breakpoint tidak dapat diatur sesuai dengan kode sumber selama debugging. Selanjutnya, mari kita lihat struktur LineNumberTable, seperti yang ditunjukkan di bawah ini:
Diantaranya, atribut_nama_index telah disebutkan di atas dan mewakili indeks kumpulan konstan, atribut_length mewakili panjang atribut, dan tabel start_pc dan line_number mewakili nomor baris bytecode dan nomor baris kode sumber. Aliran byte properti LineNumberTable dalam contoh ini adalah seperti yang ditunjukkan di bawah ini:
Setelah menganalisa metode TestClass yang pertama di atas, kita dapat menganalisis metode TestClass yang kedua dengan cara yang sama. Tangkapan layarnya adalah sebagai berikut:
Diantaranya, access_flags adalah 0×0001, name_index adalah 0x000F, dan descriptor_index adalah 0×0010. Dengan melihat kumpulan konstanta, Anda dapat mengetahui bahwa metode ini adalah metode int instanceMethod (int param) publik. Melalui cara yang mirip dengan di atas, kita dapat mengetahui bahwa atribut Code dari instanceMethod seperti terlihat pada gambar di bawah ini:
Terakhir, mari kita analisis atribut file Kelas. Dari 00000191h-00000199h adalah tabel atribut dalam file Kelas, di mana 0×0011 mewakili nama atribut. Dengan melihat kumpulan konstanta, kita dapat mengetahui bahwa nama atributnya adalah SourceFile Mari kita lihat struktur SourceFile sebagai berikut Seperti yang ditunjukkan pada gambar:
Diantaranya, atribut_length adalah panjang atribut, dan sourcefile_index menunjuk ke konstanta di kumpulan konstan yang nilainya adalah nama file kode sumber. Dalam contoh ini, tangkapan layar atribut SourceFile adalah sebagai berikut:
Diantaranya, atribut_length adalah 0×00000002, yang berarti panjangnya 2 byte, dan nilai sourcefile_index adalah 0×0012. Melihat konstanta ke-18 di kumpulan konstanta, Anda dapat mengetahui bahwa nama file kode sumber adalah TestClass .Jawa
Akhir kata, semoga teman-teman yang tertarik dengan teknologi bisa lebih banyak berkomunikasi. Weibo Pribadi: (http://weibo.com/xmuzyq)