Es scheint mir, dass die Boolesche Klasse ein idealer Kandidat ist, um als Aufzählung implementiert zu werden.
Mit Blick auf den Quellcode besteht der größte Teil der Klasse aus statischen Methoden, die unverändert in eine Aufzählung verschoben werden können. Der Rest wird als Aufzählung viel einfacher. Original vergleichen (Kommentare und statische Methoden entfernt):
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);
}
}
mit einer Enum-Version:
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";
}
}
Gibt es einen Grund, warum Boolean keine Aufzählung werden konnte?
Wenn dies der Sun-Code zum Überschreiben der equals () -Methode ist, fehlt eine sehr grundlegende Überprüfung des Vergleichs der Referenzen der beiden Objekte vor dem Vergleich ihrer Werte. So sollte meiner Meinung nach die equals () -Methode sein:
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
Highland Mark
quelle
quelle
if
) gibt, aber aus konzeptioneller / typentheoretischer Sicht sind Boolesche Werte und Aufzählungen beide Beispiele für Summentypen. Ich denke, es ist fair zu fragen, warum sie dies nicht getan haben Überbrücken Sie nicht die Lücke zwischen ihnen.valueOf(String)
(was mit dem Wert der Aufzählung in Konflikt stehen würde) und die Magie, die dahinter steckt, verpasst zu haben,getBoolean
sodassBoolean.valueOf("yes")
true und nicht false zurückgegeben wird. Beide sind Teil der 1.0-Spezifikation und erfordern eine angemessene Abwärtskompatibilität.Antworten:
Nun, ich denke, ich könnte damit beginnen, zu argumentieren, dass der Java-Programmiersprache erst mit JDK 1.5 Java-Aufzählungen hinzugefügt wurden . und deshalb war diese Lösung in den frühen Tagen, als die Boolesche Klasse definiert wurde, nicht einmal eine Alternative.
Abgesehen davon hat Java den Ruf, die Abwärtskompatibilität zwischen Releases aufrechtzuerhalten. Selbst wenn wir Ihre Lösung heute als gute Alternative betrachten, können wir dies nicht tun, ohne Tausende von Codezeilen zu unterbrechen, die bereits den alten Booleschen Wert verwenden Klasse.
quelle
new Boolean("True")
undnew Boolean("true")
kann auch einige Probleme mit der hypothetischen Enum-Implementierung verursachen.Es gibt einige Dinge, die nicht funktionieren und nicht auf überraschende Weise funktionieren, wenn Sie sie mit früheren Funktionen von Javas Booleschem Wert vergleichen.
Wir werden das Boxen ignorieren, da dies mit 1.5 hinzugefügt wurde. Wenn Sun wollte, hätten sie das hypothetisch dazu bringen können,
enum Boolean
sich genauso zu verhalten wie das Boxen, das amclass Boolean
.Es gibt jedoch andere überraschende (für den Codierer) Möglichkeiten, wie dies im Vergleich zur Funktionalität der früheren Klasse plötzlich brechen würde.
Das Problem valueOf (String)
Ein einfaches Beispiel hierfür ist:
Der Lauf dieses Codes ergibt:
Das Problem hier ist , dass ich nichts passieren kann , der nicht ist
TRUE
oderFALSE
zuvalueOf(String)
.Das ist in Ordnung ... wir überschreiben es einfach mit unserer eigenen Methode ...
Aber ... hier gibt es ein Problem. Sie können eine statische Methode nicht überschreiben .
Und so, die alle Code, um vergehen
true
oderTrue
oder ein anderer Fall gemischt werden Fehler aus - und ganz spektakulär mit einer Laufzeit Ausnahme.Noch mehr Spaß mit valueOf
Es gibt einige andere Teile, die nicht so gut funktionieren:
Denn
foo
ich bekomme nur eine Warnung über das Boxen eines bereits verpackten Wertes. Der Code für bar ist jedoch ein Syntaxfehler:Wenn wir diesen Syntaxfehler zurück in einen
String
Typ zwingen :Wir bekommen unseren Laufzeitfehler zurück:
Warum sollte jemand das schreiben? Keine Ahnung ... aber sein Code, der früher funktionierte und nicht mehr funktionierte.
Versteh mich nicht falsch, ich mag wirklich die Idee, immer nur eine Kopie eines bestimmten unveränderlichen Objekts zu haben. Die Aufzählung löst dieses Problem. Ich bin persönlich auf Herstellercode gestoßen, der Fehler im Herstellercode enthielt, der ungefähr so aussah:
das hat nie funktioniert (Nein, ich habe es nicht behoben, weil der falsche Status woanders behoben wurde, und das Beheben dieses Problems hat das auf seltsame Weise gebrochen, dass ich wirklich keine Zeit zum Debuggen hatte) . Wenn dies eine Aufzählung wäre, hätte dieser Code stattdessen funktioniert.
Die Notwendigkeit der Syntax rund um die Aufzählung (Groß- und Kleinschreibung beachten - in das dahinter stehende enumConstantDirectory eintauchen
valueOf
, Laufzeitfehler, die für die anderen Aufzählungen auf diese Weise funktionieren müssen) und die Art und Weise, wie statische Methoden funktionieren, führen jedoch dazu, dass eine Reihe von Dingen beschädigt werden, die dies verhindern ein Tropfen auf den Ersatz für einen Booleschen.quelle
of
oderfrom
Methode und ein geeignetes Javadoc hinzuzufügen .valueOf
und Boolean.valueOf () ist seit 1.0 vorhanden . Entweder kann Enums valueOf nicht als statische Methode verwenden, oder Boolean benötigt eine andere Methode als die bisher verwendete. Entweder Pausen Konvention oder Kompatibilität zu tun - und nicht mit Booleschen weder eine ENUM - Pausen sein. Daher ist die Auswahl ziemlich einfach.Boolean.valueOf(Boolean.valueOf("TRUE"))
gibt es zwei verschiedenevalueOf
Methoden:valueOf(String)
undvalueOf(boolean)
. Der Syntaxfehler liegt daran, dass Sie vergessen haben, dasvalueOf(boolean)
in zu implementierenMyBoolean
. Dann gibt es das Autounboxing zwischen den beiden Aufrufen, das in der Sprache fürBoolean
aber nicht festMyBoolean
codiert ist. Wenn SievalueOf(boolean)
MyBoolean.valueOf(MyBoolean.valueOf("FALSE").booleanValue())
Werke implementiert habenHöchstwahrscheinlich, weil der primitive
boolean
Typ keinEnum
ist und sich die Box-Versionen der primitiven Typen fast identisch mit ihrer Unbox-Version verhalten. Z.B(Die Leistung ist möglicherweise nicht dieselbe, aber das ist ein anderes Thema.)
Es wäre seltsam, wenn Sie schreiben könnten:
aber nicht:
quelle
if
Arbeit so machen kann, wie es derzeit der Fall ist. Auf der anderen Seite gibt es keine Möglichkeit, die Tatsache zu ignorieren, dass Sie zusätzliche Funktionen hinzugefügt haben,Boolean
dieboolean
dies nicht hat.Zusätzlich zum
valueOf
Problem (das ein Problem auf Java-Ebene ist, könnte es auf JVM-Ebene gut funktionieren) liegt es daran, dassBoolean
es einen öffentlichen Konstruktor hat. Das war eine schlechte Idee, die derzeit veraltet ist, aber sie ist hier, um zu bleiben.quelle
Der Grund ist, dass "bool" viel früher als "enum" Teil der Java-Sprache war. Für viele Jahre war "bool" sehr wünschenswert, während "enum" nicht verfügbar war. Erst jetzt können Sie sagen: "Wenn Enum von Anfang an verfügbar gewesen wäre, hätten wir Bool als Enum anstelle eines separaten Typs implementieren können."
In Swift, das "bool" als Aufzählung hätte ausdrücken können, gibt es drei Strukturen mit den Namen "Bool", "DarwinBoolean" und "ObjCBool", die das Protokoll "ExpressibleByBooleanLiteral" implementieren. (DarwinBoolean ist kompatibel mit einem C- oder C ++ - Bool, ObjCBool ist kompatibel mit einem Objective-C-BOOL). "true" und "false" sind vom Compiler erkannte Sonderwerte und können nur zum Initialisieren von Objekten verwendet werden, die das Protokoll "ExpressibleByBooleanLiteral" unterstützen. Bool hat eine interne Variable "_value", die eine 1-Bit-Ganzzahl enthält.
Bool ist also nicht Teil der Swift-Sprache, sondern der Standardbibliothek. true und false sind Teil der Sprache, ebenso wie das ExpressibleByBooleanLiteral-Protokoll.
quelle