Saya mengerti bahwa kompiler memerlukan ekspresi untuk diketahui pada waktu kompilasi untuk mengkompilasi switch, tetapi mengapa Foo.BA_ tidak konstan?
Sementara mereka konstan dari perspektif kode apa pun yang dieksekusi setelah bidang telah diinisialisasi, mereka bukan konstanta waktu kompilasi dalam pengertian yang diperlukan oleh JLS; lihat §15.28 Ekspresi Konstan untuk spesifikasi ekspresi konstan 1 . Ini mengacu pada §4.12.4 Variabel Final yang mendefinisikan "variabel konstan" sebagai berikut:
Kami menyebut variabel, dari tipe primitif atau tipe String, yang final dan diinisialisasi dengan ekspresi konstanta waktu kompilasi (§15.28) sebagai variabel konstan. Apakah suatu variabel adalah variabel konstan atau tidak dapat memiliki implikasi sehubungan dengan inisialisasi kelas (§12.4.1), kompatibilitas biner (§13.1, §13.4.9) dan penugasan yang pasti (§16).
Dalam contoh Anda, variabel Foo.BA * tidak memiliki inisialisasi, dan karenanya tidak memenuhi syarat sebagai "variabel konstan". Cara mengatasinya sederhana; mengubah deklarasi variabel Foo.BA * menjadi inisialisasi yang kompilasi ekspresi konstan waktu.
Dalam contoh lain (di mana inisialisasi sudah mengkompilasi ekspresi konstan waktu), menyatakan variabel sebagai final
apa yang diperlukan.
Anda bisa mengubah kode Anda untuk menggunakan konstanta enum
daripada int
konstanta, tetapi itu membawa pasangan lain dari batasan berbeda:
- Anda harus memasukkan
default
kasing, meskipun jika Anda memiliki case
untuk setiap nilai kas yang diketahui enum
; lihat Mengapa standar diperlukan untuk sakelar enum?
- The
case
label semua harus eksplisit enum
nilai-nilai, bukan ekspresi yang mengevaluasi enum
nilai-nilai.
1 - Batasan ekspresi konstan dapat diringkas sebagai berikut. Ekspresi konstan a) dapat menggunakan tipe primitif dan String
hanya, b) memungkinkan pemilihan primer yang literal (terpisah dari null
) dan variabel konstan saja, c) memungkinkan ekspresi konstan yang mungkin ditandai sebagai subekspresi, d) mengizinkan operator kecuali operator penugasan ++
,, --
atau instanceof
, dan e) memungkinkan gips tipe ke tipe primitif atau String
hanya.
Perhatikan bahwa ini tidak termasuk segala bentuk metode atau panggilan lambda new
,, .class
. .length
atau array subscript. Lebih lanjut, setiap penggunaan nilai array, enum
nilai, nilai tipe pembungkus primitif, tinju dan unboxing semuanya dikecualikan karena a).