Saya hanya bertanya-tanya mengapa pernyataan Java 7 switch
tidak mendukung null
kasus dan malah melempar NullPointerException
? Lihat baris komentar di bawah ini (contoh diambil dari artikel Tutorial Javaswitch
):
{
String month = null;
switch (month) {
case "january":
monthNumber = 1;
break;
case "february":
monthNumber = 2;
break;
case "march":
monthNumber = 3;
break;
//case null:
default:
monthNumber = 0;
break;
}
return monthNumber;
}
Ini akan menghindari if
kondisi untuk pemeriksaan nol sebelum setiap switch
penggunaan.
java
switch-statement
language-design
Prashant Bhate
sumber
sumber
null
akan menyebabkan pengecualian. Lakukanif
pemeriksaannull
, lalu masuk keswitch
pernyataan.NullPointerException
jika ekspresi mengevaluasi kenull
saat runtime] adalah hasil yang lebih baik daripada melewatkan seluruh pernyataan switch atau memilih untuk mengeksekusi pernyataan (jika ada) setelah label default (jika ada).Jawaban:
Sebagai damryfbfnetsi poin di komentar, JLS §14.11 memiliki catatan berikut:
(penekanan saya)
Sementara kalimat terakhir mengabaikan kemungkinan penggunaan
case null:
, tampaknya masuk akal dan menawarkan pandangan tentang niat desainer bahasa.Jika kita lebih suka melihat detail implementasi, posting blog oleh Christian Hujer ini memiliki beberapa spekulasi yang mendalam tentang mengapa
null
tidak diizinkan di sakelar (meskipun itu berpusat padaenum
sakelar daripadaString
sakelar):Sementara
String
sakelar diimplementasikan secara berbeda ,enum
sakelar datang lebih dulu dan mengatur preseden tentang bagaimana pengaktifan tipe referensi harus berperilaku ketika referensi tersebutnull
.sumber
case null:
jika itu akan diterapkan secara eksklusif untukString
. Saat ini semuaString
pemeriksaan memerlukan pemeriksaan null bagaimanapun juga jika kita ingin melakukannya dengan benar, meskipun sebagian besar secara implisit dengan meletakkan string konstan terlebih dahulu seperti pada"123test".equals(value)
. Sekarang kami dipaksa untuk menulis pernyataan sakelar kami seperti padaif (value != null) switch (value) {...
Secara umum
null
buruk untuk ditangani; mungkin bahasa yang lebih baik bisa hidup tanpanyanull
.Masalah Anda mungkin diselesaikan dengan
sumber
month
adalah string kosong: ini akan memperlakukannya dengan cara yang sama seperti string null.Ini tidak bagus, tetapi
String.valueOf()
memungkinkan Anda untuk menggunakan String null dalam sebuah saklar. Jika ditemukannull
, ia akan mengubahnya menjadi"null"
, jika tidak ia hanya mengembalikan String yang sama dengan yang Anda berikan. Jika Anda tidak menangani"null"
secara eksplisit, maka ini akan masuk kedefault
. Satu-satunya peringatan adalah bahwa tidak ada cara untuk membedakan antara String"null"
dannull
variabel aktual .sumber
Ini adalah upaya untuk menjawab mengapa ia melempar
NullPointerException
Output dari perintah javap di bawah ini mengungkapkan yang
case
dipilih berdasarkan kode hash dariswitch
string argumen dan karenanya melempar NPE ketika.hashCode()
dipanggil pada string nol.Artinya, berdasarkan jawaban untuk hashCode Java dapat menghasilkan nilai yang sama untuk string yang berbeda? , meski jarang, masih ada kemungkinan dua kasus dicocokkan (dua string dengan kode hash yang sama) Lihat contoh di bawah ini
javap yang
Seperti yang Anda lihat, hanya satu kasus yang dibuat untuk
"Ea"
dan"FB"
tetapi dengan duaif
kondisi untuk memeriksa kecocokan dengan setiap string kasus. Cara yang sangat menarik dan rumit untuk mengimplementasikan fungsi ini!sumber
hashCode
mengembalikan nilai yang sama pada jalan yang berbeda dari suatu program, tetapi karena hash string dimasukkan ke dalam file yang dapat dieksekusi oleh kompiler, metode hash string akhirnya menjadi bagian dari spesifikasi bahasa.Singkat cerita ... (dan semoga cukup menarik !!!)
Enum pertama kali diperkenalkan di Java1.5 ( Sep'2004 ) dan bug yang meminta pengaktifan String telah diajukan sejak lama ( Okt'95 ). Jika Anda melihat komentar yang diposting pada bug itu pada Jun'2004 , dikatakan
Don't hold your breath. Nothing resembling this is in our plans.
Sepertinya mereka menunda ( mengabaikan ) bug ini dan akhirnya meluncurkan Java 1.5 pada tahun yang sama di mana mereka memperkenalkan 'enum' dengan ordinal mulai dari 0 dan memutuskan ( terlewat ) tidak mendukung null untuk enum. Kemudian di Jawa1.7 ( Jul'2011 ) mereka mengikuti ( dipaksa) filosofi yang sama dengan String (yaitu saat membuat bytecode tidak ada pemeriksaan null yang dilakukan sebelum memanggil metode hashcode ()).Jadi saya pikir itu bermuara pada fakta enum datang pertama dan diimplementasikan dengan ordinal dimulai pada 0 karena mereka tidak dapat mendukung nilai null di blok saklar dan kemudian dengan String mereka memutuskan untuk memaksakan filosofi yang sama yaitu nilai null tidak diizinkan di blok sakelar.
TL; DR Dengan String mereka dapat menangani NPE (disebabkan oleh upaya untuk menghasilkan kode hash untuk null) saat mengimplementasikan kode java ke konversi kode byte tetapi akhirnya memutuskan untuk tidak melakukannya.
Ref: TheBUG , JavaVersionHistory , JavaCodeToByteCode , SO
sumber
Menurut Java Docs:
Karena
null
tidak memiliki tipe, dan bukan merupakan turunan dari apapun, itu tidak akan bekerja dengan pernyataan switch.sumber
null
adalah nilai yang valid untukString
,Character
,Byte
,Short
, atauInteger
referensi.Jawabannya sederhana jika Anda menggunakan sakelar dengan tipe referensi (seperti tipe primitif berkotak), kesalahan waktu proses akan terjadi jika ekspresi null karena membuka kotak itu akan membuang NPE.
jadi case null (yang ilegal) tidak akan pernah bisa dijalankan;)
sumber
if (x == null) { // the case: null part }
Saya setuju dengan komentar berwawasan (Di bawah tenda ....) di https://stackoverflow.com/a/18263594/1053496 dalam jawaban @Paul Bellora.
Saya menemukan satu alasan lagi dari pengalaman saya.
Jika 'case' bisa null itu berarti switch (variabel) null maka selama developer menyediakan case 'null' yang cocok maka kita bisa membantahnya. Tapi apa yang akan terjadi jika pengembang tidak menyediakan kasus 'null' yang cocok. Kemudian kita harus mencocokkannya dengan kasus 'default' yang mungkin bukan yang dimaksudkan oleh pengembang untuk ditangani dalam kasus default. Oleh karena itu, mencocokkan 'null' ke default dapat menyebabkan 'perilaku mengejutkan'. Karenanya melempar 'NPE' akan membuat pengembang menangani setiap kasus secara eksplisit. Saya menemukan melempar NPE dalam kasus ini sangat bijaksana.
sumber
Gunakan kelas Apache StringUtils
sumber