Saya memiliki kelas Java berikut
public class HelloWorld {
public static void main(String []args) {
}
}
Ketika saya mengkompilasi file ini dan menjalankan sha256 pada file kelas yang dihasilkan saya dapatkan
9c8d09e27ea78319ddb85fcf4f8085aa7762b0ab36dc5ba5fd000dccb63960ff HelloWorld.class
Selanjutnya saya memodifikasi kelas dan menambahkan baris kosong seperti ini:
public class HelloWorld {
public static void main(String []args) {
}
}
Sekali lagi saya menjalankan sha256 pada output mengharapkan untuk mendapatkan hasil yang sama tetapi saya malah mendapatkannya
11f7ad3ad03eb9e0bb7bfa3b97bbe0f17d31194d8d92cc683cfbd7852e2d189f HelloWorld.class
Saya telah membaca artikel TutorialsPoint ini bahwa:
Baris yang hanya berisi ruang putih, mungkin dengan komentar, dikenal sebagai baris kosong, dan Java benar-benar mengabaikannya.
Jadi pertanyaan saya adalah, karena Java mengabaikan baris kosong mengapa bytecode yang dikompilasi berbeda untuk kedua program?
Yaitu perbedaan dalam HelloWorld.class
satu 0x03
byte yang digantikan oleh 0x04
byte.
java
compilation
javac
bytecode
KNejad
sumber
sumber
Set
s abadi baru dengan pengacakan secara internal, itu bisa menghasilkan urutan yang berbeda pada setiap proses. Itu juga bisa menambahkan atribut khusus yang berisi waktu kompilasi. Dan seterusnya ...Jawaban:
Pada dasarnya, nomor baris disimpan untuk debugging, jadi jika Anda mengubah kode sumber Anda seperti yang Anda lakukan, metode Anda dimulai pada baris yang berbeda dan kelas yang dikompilasi mencerminkan perbedaannya.
sumber
end-of-transmission
singkatan dari kode ASCII 4 danend-of-text
singkatan dari kode ASCII 3-g:none
flag saat mengkompilasi (yang menghapus semua informasi debug, lihat di sini ) dan mendapatkan hash yang sama di kedua skenario.Anda dapat melihat perubahan dengan menggunakan
javap -v
yang akan menampilkan informasi verbose. Seperti lainnya yang telah disebutkan perbedaannya adalah dalam jumlah baris:Lebih tepatnya file kelas berbeda di
LineNumberTable
bagian ini:sumber
Asumsi bahwa "Jawa mengabaikan garis kosong" salah. Berikut ini cuplikan kode yang berperilaku berbeda tergantung pada jumlah baris kosong sebelum metode
main
:Jika tidak ada garis kosong sebelumnya
main
, ia mencetak"foo"
, tetapi dengan satu baris kosong sebelumnyamain
, ia mencetak"bar"
.Karena perilaku runtime berbeda,
.class
file harus berbeda, terlepas dari cap waktu atau metadata lainnya.Ini berlaku untuk setiap bahasa yang memiliki akses ke frame tumpukan dengan nomor baris, tidak hanya untuk Java.
Catatan: jika dikompilasi dengan
-g:none
(tanpa informasi debug), maka nomor baris tidak akan disertakan,getLineNumber()
selalu kembali-1
, dan program selalu dicetak"bar"
, terlepas dari jumlah jeda baris.sumber
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: -1
.-1
adalah menggunakan-g:none
bendera. Apakah ada cara lain untuk mendapatkan pengecualian ini menggunakan biasajavac
?-g
opsi. Ada juga-g:vars
dan-g:source
yang mencegah generasiLineNumberTable
.Selain detail nomor baris untuk debugging, manifes Anda juga dapat menyimpan waktu dan tanggal pembuatan. Ini tentu saja akan berbeda setiap kali Anda kompilasi.
sumber