Output aneh dalam String di Java [duplikat]

Kemungkinan Duplikat:
Menggabungkan string null di Java

Silakan temukan di bawah cuplikan kode

String str = null;
str = str + "hi";

System.out.println(str)

Output dari kode di atas adalah nullhi.

Saya pikir keluarannya akan menjadi hi, jadi saya terkejut dengan keluarannya dan tidak dapat menemukan alasan di baliknya.

Bisakah seseorang tolong jelaskan.


person Anand    schedule 30.10.2012    source sumber
comment
Saya hanya butuh 5 detik untuk mendapatkan link postingan tersebut. Silakan gunakan Google secara teratur.   -  person Rohit Jain    schedule 30.10.2012
comment
saya tidak yakin dengan teks yang akan digunakan untuk pencarian google, jadi langsung diposting di sini.   -  person Anand    schedule 30.10.2012


Jawaban (6)


Dari JLS.

http://docs.Oracle.com/javase/specs/jls/se7/html/index.html

§15.18.1. Operator Penggabungan String + (referensi)

Jika hanya satu ekspresi operan yang bertipe String, maka konversi string (§5.1.11) dilakukan pada operan lain untuk menghasilkan string pada saat run-time.

§5.1.11. Konversi String (referensi)

Jika referensinya null, maka dikonversi ke string "null" (empat karakter ASCII n, u, l, l).

person jn1kk    schedule 30.10.2012

Ini karena metode append. + dikonversi sebagai operasi penambahan StringBuilder atau StringBuffer.

public AbstractStringBuilder append(String str) {
if (str == null) str = "null";

public static String valueOf(Object obj) {
return (obj == null) ? "null" : obj.toString();
}

Di bawah ini adalah kode byte yang dihasilkan untuk program Anda

 0  aconst_null
 1  astore_1 [str]
 2  new java.lang.StringBuilder [16]
 5  dup
 6  aload_1 [str]
 7  invokestatic java.lang.String.valueOf(java.lang.Object) : java.lang.String [18]
10  invokespecial java.lang.StringBuilder(java.lang.String) [24]
13  ldc <String "hi"> [27]
15  invokevirtual java.lang.StringBuilder.append(java.lang.String) : java.lang.StringBuilder [29]
18  invokevirtual java.lang.StringBuilder.toString() : java.lang.String [33]
21  astore_1 [str]
22  getstatic java.lang.System.out : java.io.PrintStream [37]
25  aload_1 [str]
26  invokevirtual java.io.PrintStream.println(java.lang.String) : void [43]
29  return

Jadi kode Anda sebenarnya diubah menjadi append(null) dan kemudian append("hi") itulah sebabnya Anda mendapatkan keluaran seperti itu

Juga didokumentasikan dengan jelas di 15.18.1. String Concatenation Operator +

Implementasi dapat memilih untuk melakukan konversi dan penggabungan dalam satu langkah untuk menghindari pembuatan dan kemudian membuang objek String perantara. Untuk meningkatkan kinerja penggabungan string berulang, kompiler Java dapat menggunakan kelas StringBuffer atau teknik serupa untuk mengurangi jumlah objek String perantara yang dibuat dengan mengevaluasi ekspresi.

person Amit Deshpande    schedule 30.10.2012
comment
Ini adalah fakta yang bagus dan menyenangkan, tetapi alasan sebenarnya dari pengamatan OP tidak terletak pada detail implementasi kompiler, tetapi pada JLS yang dengan jelas menentukan semantik operator penggabungan. - person Marko Topolnik; 30.10.2012
comment
@MarkoTopolnik Komentar Anda selalu menambah pengetahuan saya. Menambahkan referensi seperti itu dari JLS - person Amit Deshpande; 30.10.2012

null adalah nilai yang dicetak jika Anda mencoba mencetak referensi nol di java.

person Paul Morie    schedule 30.10.2012

Saat Anda menggabungkan nilai-nilai yang tidak semuanya string, nilai-nilai yang bukan string akan dikonversi seolah-olah oleh String.valueOf. String.valueOf(null) adalah string "null".

person Ian Roberts    schedule 30.10.2012
comment
Tapi str adalah sebuah String, jadi ini tidak menjelaskannya. - person Marko Topolnik; 30.10.2012
comment
null bukan sebuah String (memang bukan objek apa pun). - person Ian Roberts; 30.10.2012
comment
Apakah Anda bermaksud menyiratkan bahwa kompiler membuat kode yang memeriksa secara dinamis apakah akan menggunakan String.valueOf? Implikasi Anda salah: String.valueOf selalu dipanggil untuk semua argumen yang diketik referensi ke +. - person Marko Topolnik; 30.10.2012
comment
Sebenarnya, saya mencoba menjelaskan efeknya, bukan mekanismenya. - person Ian Roberts; 30.10.2012
comment
Deskripsi efeknya juga lebih sederhana jika Anda hanya mengatakan semua operan ditransformasikan seolah-olah oleh String.valueOf. - person Marko Topolnik; 30.10.2012

Itu adalah keputusan yang dibuat sejak awal oleh para pencipta Java. Nilai null apa pun yang digabungkan ke string akan dihasilkan sebagai null. Hal ini masuk akal jika Anda membayangkan mencoba mengeluarkan pesan log:

String personName = null;
System.out.println("Person name is: " + personName);

Hasil:

Nama orang adalah: null

Perilaku itu dapat membantu Anda saat melakukan debug karena Anda tahu bahwa variabel tersebut sebenarnya nol (sebagai lawan dari string kosong, misalnya).

Mereka bisa saja memilih untuk hanya melemparkan pengecualian ketika Anda mencoba melakukan ini, tapi itu akan menyebabkan banyak hal mencapai titik impas ketika melakukan sesuatu seperti membuat pesan log atau string pengecualian.

Mereka juga bisa melakukan seperti yang Anda harapkan dan membuat nilai nol mendapatkan keluaran sebagai string kosong. Inilah yang dilakukan kerangka .NET. Namun pada akhirnya, bukan itu yang mereka putuskan.

person StriplingWarrior    schedule 30.10.2012

Dalam contoh yang Anda tunjukkan, Anda menggabungkan string null dengan hi sehingga keluaran yang dihasilkan adalah
nullhi

String str = null;
str = str + "hi";

System.out.println(str);


as str=str+"hi "//shows one string is concatenating with the other

jadi output yang Anda dapatkan benar.

person Abhishekkumar    schedule 30.10.2012