Jadi, saya sedang mengerjakan kelas ini yang memiliki beberapa konstanta statis:
public abstract class Foo {
...
public static final int BAR;
public static final int BAZ;
public static final int BAM;
...
}
Lalu, saya ingin cara untuk mendapatkan string yang relevan berdasarkan konstanta:
public static String lookup(int constant) {
switch (constant) {
case Foo.BAR: return "bar";
case Foo.BAZ: return "baz";
case Foo.BAM: return "bam";
default: return "unknown";
}
}
Namun, ketika saya kompilasi, saya mendapatkan constant expression required
kesalahan pada masing-masing 3 label kasus.
Saya mengerti bahwa kompiler memerlukan ekspresi untuk diketahui pada waktu kompilasi untuk mengkompilasi switch, tetapi mengapa tidak Foo.BA_
konstan?
java
compile-time-constant
Austin Hyde
sumber
sumber
public static final int
S tersebar di seluruh JDK, jadi itulah yang saya ikuti.Jawaban:
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:
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
daripadaint
konstanta, tetapi itu membawa pasangan lain dari batasan berbeda:default
kasing, meskipun jika Anda memilikicase
untuk setiap nilai kas yang diketahuienum
; lihat Mengapa standar diperlukan untuk sakelar enum?case
label semua harus eksplisitenum
nilai-nilai, bukan ekspresi yang mengevaluasienum
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 darinull
) dan variabel konstan saja, c) memungkinkan ekspresi konstan yang mungkin ditandai sebagai subekspresi, d) mengizinkan operator kecuali operator penugasan++
,,--
atauinstanceof
, dan e) memungkinkan gips tipe ke tipe primitif atauString
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).sumber
Anda mendapatkan ekspresi Konstan yang diperlukan karena Anda meninggalkan nilai dari konstanta Anda. Mencoba:
sumber
Saya mendapatkan kesalahan ini di Android, dan solusi saya hanya menggunakan:
dari pada
sumber
Karena mereka tidak menyusun konstanta waktu. Pertimbangkan kode yang valid berikut ini:
Anda hanya bisa mengetahui nilai
BAR
dalam runtime.sumber
public static final int BAR = new Random().nextInt()
bekerjanew Random().nextInt()
mengembalikan nilai yang sama?Anda dapat menggunakan enum seperti dalam contoh ini:
Sumber: Ganti pernyataan dengan enum
sumber
enum Codes { CODE_A(1), CODE_B(2); private mCode; Codes(int i) { mCode = i; } public int code() { return mCode; } }
<br/> Ketika saya mencoba menggunakan enum di saklar saya mendapatkan kesalahan yang sama ... <br/>switch(field) { case Codes.CODE_A.code() : // do stuffs.. ; }
<br/> Apakah mungkin untuk menyelesaikan masalah?Ini dijawab berabad-abad yang lalu dan mungkin tidak relevan, tetapi untuk berjaga-jaga. Ketika saya dihadapkan dengan masalah ini, saya hanya menggunakan
if
pernyataan dan bukannyaswitch
, itu memecahkan kesalahan. Ini tentu saja merupakan solusi dan mungkin bukan solusi yang "tepat", tetapi dalam kasus saya itu sudah cukup.sumber
switch
umumnya lebih cepat daripada panjangif-else
, karenaswitch
hanya memeriksa kondisi satu kali , sementara denganif-else
Anda mungkin perlu memeriksa semua kondisi sebelum menemukan yang tepat.Terkadang variabel switch juga bisa membuat kesalahan itu misalnya:
Untuk menyelesaikannya Anda harus melemparkan variabel ke int (dalam hal ini). Begitu:
sumber
Mendapat kesalahan ini di Android saat melakukan sesuatu seperti ini:
meskipun mendeklarasikan konstanta:
public static final String ADMIN_CONSTANT= "Admin";
Saya menyelesaikan masalah dengan mengubah kode saya menjadi ini:
sumber
Dalam kasus saya, saya mendapatkan pengecualian ini karena
dalam kasus kedua saya memanggil konstanta dari instance
var.MODIFICAR_KM:
tetapi saya harus menggunakanVariablesKmDialog.OBTENER_KM
langsung dari kelas.sumber
Jika Anda menggunakannya dalam sakelar maka Anda harus mendapatkan tipe enum bahkan sebelum Anda memasukkan nilai itu ke sakelar. Misalnya :
Dan enum seperti:
sumber
Kode di bawah ini cukup jelas. Kita dapat menggunakan enum dengan case switch:
Berdasarkan nilai-nilai kelas dari enum dapat dipetakan:
Semoga bermanfaat :)
sumber
Saya sarankan menggunakan cara berikut:
sumber
private Animal(String name) { this.name = name; }
Saya merekomendasikan Anda untuk menggunakan enum :)
Lihat ini:
Maka Anda dapat menggunakannya seperti ini:
sumber