Apa perbedaan dalam memori antara variabel yang ditugaskan ke nol dan yang tidak ditugaskan

8

Apa perbedaan dalam memori antara variabel yang ditugaskan ke nol dan yang tidak ditugaskan?

Saya tahu bahwa ada perbedaan dalam penggunaan, tetapi apa perbedaan dalam memori?

abu_abdelbarr
sumber
1
Berbagi penelitian Anda membantu semua orang . Beri tahu kami apa yang telah Anda coba dan mengapa itu tidak memenuhi kebutuhan Anda. Ini menunjukkan bahwa Anda telah meluangkan waktu untuk mencoba membantu diri sendiri, itu menyelamatkan kami dari mengulangi jawaban yang jelas, dan yang paling penting itu membantu Anda mendapatkan jawaban yang lebih spesifik dan relevan. Lihat juga Cara Meminta
nyamuk

Jawaban:

11

Tidak ada perbedaan antara keduanya "dalam memori."

Dari Spesifikasi Bahasa Jawa, 4.12.5. Nilai Awal Variabel :

Setiap variabel dalam suatu program harus memiliki nilai sebelum nilainya digunakan:

  • Setiap variabel kelas, variabel instan, atau komponen array diinisialisasi dengan nilai default ketika dibuat (§15.9, §15.10.2):

...

    • Untuk semua jenis referensi (§4.3), nilai standarnya adalah nol.

...

    • Variabel lokal (§14.4, §14.14) harus secara eksplisit diberi nilai sebelum digunakan, baik dengan inisialisasi (§14.4) atau penugasan (§15.26), dengan cara yang dapat diverifikasi menggunakan aturan untuk penugasan tertentu (§ 16 (Penugasan Pasti)).

Variabel referensi di tingkat kelas atau objek akan diberi nilai nol.

Variabel referensi pada level metode (tumpukan) akan memiliki nilai yang tidak ditentukan (menggunakan istilah C ++). Dalam praktiknya, ini sering nol, tetapi standar tidak menentukan apa yang ada dalam variabel referensi, hanya saja harus ditetapkan sebelum digunakan. Menggunakan variabel referensi pada tumpukan dengan cara apa pun selain penugasan sebagai penggunaan pertama akan menghasilkan kesalahan kompilasi.


sumber
Ketika Anda mendeklarasikan variabel tanpa menginisialisasi ke nol, kemudian menginisialisasi dalam if-thenblok, kompiler memberi tahu Anda bahwa variabel mungkin diinisialisasi sebelumnya dalam kode jika thenblok tidak dieksekusi. Jika Anda menginisialisasi ke nullkompilasi kode. Mengapa itu diberikan bahwa "referensi yang tidak secara eksplisit menetapkan nilai akan memiliki nilai nol" ?
Tulains Córdova
@Snowman Bukankah itu detail implementasi? Hanya variabel kelas, variabel instan, dan komponen array yang harus diinisialisasi ke nilai standarnya. Tidak ada persyaratan pada variabel lokal dan Anda tidak dapat menggunakannya sebelum mereka diinisialisasi. Jika Anda melihat variabel lokal yang tidak diinisialisasi dalam memori Anda akan melihat apa pun yang terjadi dengan implementasi itu, yang mungkin tidak melibatkan inisialisasi nullkarena itu akan menjadi pekerjaan yang tidak perlu untuk melakukannya.
Doval
@Snowman - Karena ilegal menggunakan lokal sebelum itu diberi nilai, apakah variabel lokal yang tidak diinisialisasi diberikan nilai awal adalah detail implementasi.
David Hammen
1
Silakan lihat hasil edit saya yang terbaru. Saya menyalahkan kopi yang tidak mencukupi pada Senin pagi.
4

Apa perbedaan antara variabel yang ditetapkan ke nol dan yang lainnya yang tidak ditetapkan dalam memori?

Tidak ada yang namanya variabel unassigned di Java. Anggota data kelas yang tidak memiliki tugas eksplisit diberi nilai default untuk tipe, null untuk objek, atau sesuatu yang mirip dengan 0 untuk tipe primitif.

Variabel lokal hidup di stack. (Penduduk lokal non-primitif seperti MyType foojuga tinggal di tumpukan, sebagai referensi.) Alokasi tumpukan sederhana. Jika sebuah blok berisi deklarasi untuk variabel lokal, ruang yang dibutuhkan oleh variabel-variabel lokal dicadangkan di stack. Apakah nilai ditugaskan ke variabel lokal pada penyesuaian tumpukan untuk mengakomodasi variabel lokal itu tidak relevan.

Alasannya tidak masalah adalah apakah variabel lokal diberi atau tidak diberi nilai pada saat eksekusi memasuki blok ada dua. Salah satu alasannya adalah ukuran yang dibutuhkan tidak berubah. Primitif memiliki ukuran tetap, dan non-primitif sebenarnya adalah referensi. (Objek yang direferensikan hidup pada heap daripada stack.) Alasan kedua adalah bahwa menggunakan variabel lokal yang belum diberi nilai adalah kesalahan kompilasi. Ini meninggalkannya ke Java runtime apakah akan memberikan nilai (tidak harus default) ke variabel lokal yang dideklarasikan tetapi tidak ditugaskan.

David Hammen
sumber
Di suatu tempat dalam jawaban Anda adalah penjelasan untuk ini: Ketika Anda mendeklarasikan variabel tanpa menginisialisasi ke nol, kemudian menginisialisasi dalam if-thenblok, kompiler memberitahu Anda bahwa variabel mungkin diinisialisasi di depan dalam kode jika thenblok tidak dieksekusi. Jika Anda menginisialisasi ke nullkompilasi kode. Mengapa itu diberikan bahwa "referensi yang tidak secara eksplisit menetapkan nilai akan memiliki nilai nol" ? Tetapi itu masih belum cukup jelas bagi saya. Bisakah Anda menjelaskannya dengan kata lain?
Tulains Córdova
2
Variabel lokal tidak perlu diberi nilai awal. Mereka harus diberi nilai sebelum penggunaan awal. Apakah memori yang terkait dengan variabel itu diberi nilai awal yang eksplisit, bahkan dalam kasus deklarasi tanpa penugasan, adalah detail implementasi. Memori ada (itulah cara tumpukan bekerja), tetapi ruang memori itu bisa dibiarkan diisi dengan apa pun yang terjadi di memori itu sebelum menyesuaikan tumpukan.
David Hammen
@ user61852 - Bahwa referensi yang tidak secara eksplisit menetapkan nilai akan memiliki nilai nol adalah benar untuk anggota kelas, tetapi tidak harus untuk variabel lokal. Jika Anda mengkompilasi kode Anda dengan debug diaktifkan, kompiler hampir pasti akan menginisialisasi variabel lokal non-primitif Anda yang belum diinisialisasi null. Ini sangat menyederhanakan pengembangan debugger Java. Tetapi bagaimana jika Anda kompilasi dengan debug dinonaktifkan? Sekarang inisialisasi itu adalah pekerjaan tambahan yang tidak perlu. Apa yang ada di memori itu tidak relevan karena diketahui bahwa memori akan berisi nilai yang valid pada penggunaan pertama.
David Hammen
Dari perspektif bytecode, variabel lokal dialokasikan pada stack. Akan tetapi, JITter dapat memutuskan untuk memutuskan bahwa entri stack tertentu seharusnya tidak benar-benar disimpan di stack, tetapi penyimpanan ke dan banyak dari entri tersebut harus diarahkan pada register CPU tertentu. Lebih lanjut, jika JITter menentukan bahwa setelah eksekusi mencapai titik tertentu, tidak ada cara entri tumpukan akan dibaca tanpa ditulis ulang, itu mungkin menetapkan ulang register terkait entri itu untuk tujuan lain.
supercat
1

Pertama, benar-benar tidak perlu khawatir tentang ruang yang digunakan oleh variabel lokal. Dalam satu baris saya dapat mengalokasikan array 100.000 bilangan bulat yang akan mengambil lebih banyak ruang daripada semua variabel lokal yang akan Anda gunakan.

Kedua, kode Anda dikompilasi oleh kompiler yang cenderung pintar. Jika variabel Anda tidak diinisialisasi, itu tidak digunakan (karena kompiler tidak mengizinkan untuk menggunakan variabel yang tidak diinisialisasi). Tetapi jika Anda menginisialisasi ke nol, itu masih tidak digunakan! Compiler akan dengan mudah mengetahui bahwa itu tidak digunakan dan tidak benar-benar menggunakan ruang untuk variabel sama sekali. Sekalipun digunakan, kompiler akan dengan mudah mengetahui bahwa nilainya nil, dan menggunakan nil sebagai ganti variabel.

Namun ketiga, ini semua optimasi mikro yang tidak akan membantu Anda mengoptimalkan program dengan cara apa pun. Anda mencoba menyimpan empat atau delapan byte. Berkonsentrasi pada penyimpanan megabita jika Anda ingin menyimpan apa pun.

Dan terakhir, sementara beberapa orang mengklaim variabel harus selalu diinisialisasi, itu tidak benar di Jawa. Anda seharusnya hanya mengatur variabel ke nilai yang bermakna. Katakanlah Anda ingin menetapkan variabel ke nama seseorang, dan Anda lupa melakukan ini dalam satu jalur kode. Jika Anda secara buta menginisialisasi variabel menjadi nil, kompiler tidak dapat memberi tahu Anda. Tanpa inisialisasi, kompiler dapat dan akan memberi tahu Anda tentang kesalahan Anda.

gnasher729
sumber