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 finalapa yang diperlukan.
Anda bisa mengubah kode Anda untuk menggunakan konstanta enumdaripada intkonstanta, tetapi itu membawa pasangan lain dari batasan berbeda:
- Anda harus memasukkan
defaultkasing, meskipun jika Anda memiliki caseuntuk setiap nilai kas yang diketahui enum; lihat Mengapa standar diperlukan untuk sakelar enum?
- The
caselabel semua harus eksplisit enumnilai-nilai, bukan ekspresi yang mengevaluasi enumnilai-nilai.
1 - Batasan ekspresi konstan dapat diringkas sebagai berikut. Ekspresi konstan a) dapat menggunakan tipe primitif dan Stringhanya, 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 Stringhanya.
Perhatikan bahwa ini tidak termasuk segala bentuk metode atau panggilan lambda new,, .class. .lengthatau array subscript. Lebih lanjut, setiap penggunaan nilai array, enumnilai, nilai tipe pembungkus primitif, tinju dan unboxing semuanya dikecualikan karena a).