Tampak bagi saya bahwa kelas Boolean adalah kandidat ideal untuk diimplementasikan sebagai enum.
Melihat kode sumber, sebagian besar kelas adalah metode statis yang dapat dipindahkan tidak berubah ke enum, sisanya menjadi lebih sederhana sebagai enum. Bandingkan yang asli (komentar dan metode statis dihapus):
public final class Boolean implements java.io.Serializable,
Comparable<Boolean>
{
public static final Boolean TRUE = new Boolean(true);
public static final Boolean FALSE = new Boolean(false);
private final boolean value;
public Boolean(boolean value) {
this.value = value;
}
public Boolean(String s) {
this(toBoolean(s));
}
public boolean booleanValue() {
return value;
}
public String toString() {
return value ? "true" : "false";
}
public int hashCode() {
return value ? 1231 : 1237;
}
public boolean equals(Object obj) {
if (obj instanceof Boolean) {
return value == ((Boolean)obj).booleanValue();
}
return false;
}
public int compareTo(Boolean b) {
return compare(this.value, b.value);
}
}
dengan versi enum:
public enum Boolean implements Comparable<Boolean>
{
FALSE(false), TRUE(true);
private Boolean(boolean value) {
this.value = value;
}
private final boolean value;
public boolean booleanValue() {
return value;
}
public String toString() {
return value ? "true" : "false";
}
}
Apakah ada alasan mengapa Boolean tidak bisa menjadi enum?
Jika ini adalah kode Sun untuk menimpa metode equals (), maka tidak ada pemeriksaan mendasar untuk membandingkan referensi dari dua objek sebelum membandingkan nilainya. Beginilah menurut saya metode equals () seharusnya:
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj instanceof Boolean) {
return value == ((Boolean)obj).booleanValue();
}
return false;
}
java
api
source-code
Tanda Dataran Tinggi
sumber
sumber
if
) tetapi dari sudut pandang teori konseptual / tipe boolean dan enum keduanya adalah contoh tipe penjumlahan, jadi saya pikir wajar untuk bertanya mengapa mereka tidak akan menjembatani kesenjangan di antara mereka.valueOf(String)
(yang akan bertentangan dengan nilai enum dari) dan keajaiban di belakanggetBoolean
yang dapat membuatnya sehinggaBoolean.valueOf("yes")
mengembalikan true daripada false. Keduanya merupakan bagian dari spesifikasi 1.0 dan akan membutuhkan kompatibilitas ke belakang yang sesuai.Jawaban:
Yah, saya kira saya bisa mulai dengan berpendapat bahwa enumerasi Java tidak ditambahkan ke bahasa pemrograman Java sampai JDK 1.5. dan karena itu solusi ini bahkan bukan alternatif di masa-masa awal ketika kelas Boolean didefinisikan.
Yang sedang berkata, Java memiliki reputasi menjaga kompatibilitas ke belakang antara rilis dan, bahkan jika kami, hari ini, dapat mempertimbangkan solusi Anda sebagai alternatif yang baik, kami tidak dapat melakukannya tanpa memutus ribuan baris kode di luar sana yang sudah menggunakan Boolean lama kelas.
sumber
new Boolean("True")
dannew Boolean("true")
juga dapat menyebabkan beberapa masalah dengan implementasi enum hipotetis.Ada beberapa hal yang tidak berfungsi, dan tidak bekerja dengan cara yang agak mengejutkan ketika Anda membandingkannya dengan fungsi boolean Java sebelumnya.
Kita akan mengabaikan tinju karena itu adalah sesuatu yang ditambahkan dengan 1,5. Hipotetis, jika Sun ingin mereka bisa membuat
enum Boolean
untuk berperilaku seperti tinju yang dilakukan diclass Boolean
.Namun, ada cara mengejutkan lainnya (ke pembuat kode) yang tiba-tiba akan rusak dibandingkan dengan fungsi dari kelas sebelumnya.
Masalah valueOf (String)
Contoh sederhana dari ini adalah:
Menjalankan kode ini memberikan:
Masalahnya di sini adalah bahwa saya tidak bisa melewati apa pun yang tidak
TRUE
atauFALSE
untukvalueOf(String)
.Tidak apa-apa ... kita hanya akan menimpanya dengan metode kita sendiri ...
Tapi ... ada masalah di sini. Anda tidak dapat mengganti metode statis .
Jadi, semua kode yang diedarkan
true
atauTrue
kasus campuran lainnya akan error - dan sangat spektakuler dengan pengecualian runtime.Lebih menyenangkan dengan valueOf
Ada beberapa bit lain yang tidak berfungsi dengan baik:
Sebab
foo
, saya baru saja mendapat peringatan tentang tinju nilai yang sudah kemas. Namun, kode untuk bilah adalah kesalahan sintaksis:Jika kami memaksa kesalahan sintaks itu kembali ke
String
jenis:Kami mendapatkan kesalahan runtime kami kembali:
Mengapa ada orang yang menulis itu? Entahlah ... tetapi kodenya yang dulu berfungsi dan tidak lagi berfungsi.
Jangan salah paham, saya benar-benar menyukai gagasan hanya satu salinan dari objek abadi yang diberikan. Enum memecahkan masalah ini. Saya pribadi menemukan kode vendor yang memiliki bug di dalamnya dari kode vendor yang terlihat seperti ini:
itu tidak pernah berhasil (Tidak, saya tidak memperbaikinya karena keadaan yang salah diperbaiki di tempat lain, dan memperbaiki ini mematahkan hal itu dengan cara yang aneh bahwa saya benar-benar tidak punya waktu untuk men-debug) . Jika ini adalah enum, kode itu akan berfungsi sebagai gantinya.
Namun, kebutuhan sintaksis di sekitar enum (case sensitif - gali ke dalam enumConstantDirectory di belakang
valueOf
, kesalahan runtime yang perlu bekerja seperti itu untuk enum lain) dan cara metode statis bekerja menyebabkan sejumlah hal rusak yang mencegahnya dari menjadi setetes pengganti Boolean.sumber
of
ataufrom
metode dan javadoc yang sesuai.valueOf
dan Boolean.valueOf () telah ada sejak 1.0 . Entah Enums tidak akan dapat menggunakan valueOf sebagai metode statis, atau Boolean akan membutuhkan metode yang berbeda dari yang telah digunakan. Melakukan istirahat konvensi atau kompatibilitas - dan tidak memiliki Boolean menjadi istirahat enum juga. Dari sini, pilihannya cukup sederhana.Boolean.valueOf(Boolean.valueOf("TRUE"))
, ada duavalueOf
metode yang berbeda :valueOf(String)
danvalueOf(boolean)
. Kesalahan sintaksis adalah karena Anda lupa mengimplementasikanvalueOf(boolean)
inMyBoolean
. Lalu ada autounboxing antara dua panggilan, yang hardcoded dalam bahasa untukBoolean
tetapi tidakMyBoolean
. Jika Anda menerapkanvalueOf(boolean)
MyBoolean.valueOf(MyBoolean.valueOf("FALSE").booleanValue())
karyaKemungkinan besar karena
boolean
tipe primitif bukanEnum
, dan versi kotak tipe primitif berperilaku hampir identik dengan versi unboxed mereka. Misalnya(Performanya mungkin tidak sama, tapi itu subjek yang berbeda.)
Agak aneh jika Anda bisa menulis:
tapi tidak:
sumber
if
pekerjaan seperti saat ini. Di sisi lain, tidak ada cara untuk mengabaikan fakta bahwa Anda telah menambahkan fungsionalitas tambahanBoolean
yangboolean
tidak dimiliki.Selain
valueOf
masalah (yang merupakan masalah di tingkat Jawa, itu bisa berfungsi dengan baik di tingkat JVM), itu karenaBoolean
memiliki konstruktor publik. Itu adalah ide yang buruk, saat ini sudah usang, tetapi itu adalah salah satu yang tinggal di sini.sumber
Alasannya adalah bahwa "bool" adalah bagian dari bahasa Jawa jauh lebih awal daripada "enum". Selama bertahun-tahun, "bool" sangat diinginkan untuk dimiliki, sementara "enum" tidak tersedia. Hanya sekarang Anda dapat mengatakan "jika enum telah tersedia sejak awal, maka kami bisa menerapkan bool sebagai enum daripada tipe yang terpisah".
Di Swift, yang bisa menyatakan "bool" sebagai enum, ada tiga struct bernama "Bool", "DarwinBoolean" dan "ObjCBool" yang mengimplementasikan protokol "ExpressibleByBooleanLiteral". (DarwinBoolean kompatibel dengan bool C atau C ++, ObjCBool kompatibel dengan Objective-C BOOL). "true" dan "false" adalah nilai khusus yang dikenali oleh kompiler, dan hanya dapat digunakan untuk menginisialisasi objek yang mendukung protokol "ExpressibleByBooleanLiteral". Bool memiliki variabel internal "_value" yang mengandung integer satu bit.
Jadi Bool bukan bagian dari bahasa Swift, tetapi dari perpustakaan standar. benar dan salah adalah bagian dari bahasa, dan begitu juga protokol ExpressibleByBooleanLiteral.
sumber